Bind the property of an element in UserControl to

2019-08-04 04:34发布

First of all, I'm very very new to the concept of MVVM. I'm even not sure what I'm asking here is even a MVVM question. So please forgive me for my mistakes I may make here.

I'm trying to Bind the Foreground property of a TextBlock in a UserControl to TextColor property in MyViewModel.cs. I also want to be able to change the TextColor property via code. For example by clicking a button. How can I achieve all of these.

Here is the complete non-working error-free code I've put up so far!

MainWindow:

<Window x:Class="WpfApplication23.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        xmlns:local="clr-namespace:WpfApplication23">
    <StackPanel>
        <local:UserControl1 x:Name="MyControl"/>
        <Button Content="Change Color" 
            Width="200" 
            Height="30" 
            Click="ButtonBase_OnClick"/>
    </StackPanel>
</Window> 

MainWindow.xaml.cs:

using System.Windows;    
namespace WpfApplication23
{
    public partial class MainWindow : Window
    {

        public MainWindow()
        {
            InitializeComponent();

            DataContext = new MyViewModel();

        }

        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            // Change the `TextColor` property in `MyViewModel.cs`
        }
    }
}

UserControl:

<UserControl x:Class="WpfApplication23.UserControl1"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    <Grid>
        <TextBlock Text="Sample Text" Foreground="{Binding TextColor}"/>
    </Grid>
</UserControl>

MyViewModel.cs:

public class MyViewModel
{
    public Brush TextColor;

    public MyViewModel()
    {
        TextColor = Brushes.Red;
    }
}

标签: c# wpf xaml mvvm
1条回答
孤傲高冷的网名
2楼-- · 2019-08-04 05:04

Your MyViewModel class should declare a public TextColor property, not a public field (and you may rename it to TextBrush, because it is a Brush, not a Color). In order to be able to notify about changes of the property value, it should also implement the INotifyPropertyChanged interface.

public class MyViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private Brush textColor = Brushes.Red;
    public Brush TextColor
    {
        get { return textColor; }
        set
        {
            textColor = value;
            RaisePropertyChanged("TextColor");
        }
    }

    private void RaisePropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

In your button click handler you may now cast the DataContext to your MyViewModel class, and set the property.

private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
    var vm = (MyViewModel)DataContext;
    vm.TextColor = Brushes.Blue;
}

An even better solution to change the color would be to bind the Button's Command property to an ICommand in your view model. You may start reading about this in the Commanding Overview article on MSDN.

查看更多
登录 后发表回答