Search code examples
wpfmvvmdatatrigger

How to get data binding to work with a simple MVVM structure


After getting the right answer, I thought I should update this to show the working code for people to have a future reference:

MainWindow.xaml

<Grid>
    <Grid.Resources>
        <local:ValueConverters x:Key="ValueConverters"></local:ValueConverters>
    </Grid.Resources>
    <TextBox Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}">
        <TextBox.Style>
            <Style>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding Path=Text,Converter={StaticResource ValueConverters}}" Value="True">
                        <Setter Property="TextBox.Foreground" Value="Red"></Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBox.Style>
    </TextBox>
</Grid>

MainWindow.xaml.cs

public partial class MainWindow : MetroWindow
{
     private readonly DataBindingViewModel _vm = new DataBindingViewModel();

    public MainWindow()
    {
        InitializeComponent();
        DataContext = _vm;
    }
}

DataBindingViewModel.cs

public class DataBindingViewModel : INotifyPropertyChanged
{
    private string _text;

    public string Text
    {
        get
        {
            return this._text;
        }
        set
        {
            this._text = value;
            if (null != PropertyChanged)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs("Text"));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

ValueConverters

public class ValueConverters : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (null != value)
        {
            if (value.ToString() == "1")
                return true;
        }
        return false;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return null;
    }
}

The above now works:)


Solution

  • In your MainWindow's XAML the DataContext is set to an instance of ValueConverters:

    <Window.DataContext>
        <local:ValueConverters/>
    </Window.DataContext>
    

    That doesn't seem to make sense. You should replace it with

    <Window.DataContext>
        <local:DataBindingViewModel/>
    </Window.DataContext>
    

    You would not have to set the DataContext again in the MainWindow's constructor, but perhaps still assign the private field (for later use) like this:

    private readonly DataBindingViewModel _vm;
    
    public MainWindow()
    {
        InitializeComponent();
        _vm = (DataBindingViewModel)DataContext;
    }
    

    Alternatively, do not set the DataContext at all in XAML, and create it in code behind like this:

    private readonly DataBindingViewModel _vm = new DataBindingViewModel();
    
    public MainWindow()
    {
        InitializeComponent();
        DataContext = _vm;
    }