Tidbits

Annoyingly hard to find WPF Binding “Error”

TL;DR: Did you really implement INotifyPropertyChanged? Are you sure?

Happened to me recently. Took me an embarrassingly long time to find.
Have a look at this WPF Window:

Here’s the (relevant) XAML:

<StackPanel Margin="5">
        <CheckBox IsChecked="{Binding Bar}" Content="A is selected"/>
        <ComboBox Text="{Binding Foo}">
            <ComboBox.Items>
                <ComboBoxItem>A</ComboBoxItem>
                <ComboBoxItem>B</ComboBoxItem>
                <ComboBoxItem>C</ComboBoxItem>
            </ComboBox.Items>
        </ComboBox>
        <TextBlock Text="{Binding Foo}"/>
    </StackPanel>

And the underlying model:

private string _foo;
 
public string Foo
{
    get => _foo;
    set
    {
        if (value == _fooreturn;
        _foo = value;
        OnPropertyChanged();
        OnPropertyChanged(nameof(Bar));
    }
}
 
public bool Bar
{
    get => _foo=="A";
    set
    {
        if (value)
            Foo = "A";
    }
}

Essentially: In the ComboBox I can select A, B, or C, and whatever is selected will be shown in the TextBlock below it.
Both are bound to the same property in the model.
The CheckBox is bound to a computed property, based on the selection, and can change it to A.

A while back I was working an a WPF project that involved a scenario like this. For some reason though, it suddenly stopped working properly. Applying the “error” to this demo, the TextBlock would still reflect whatever you select in the ComboBox. The CheckBox however, would not react. And checking the CheckBox would not set the ComboBox or TextBlock to A anymore.
My first thought was, that I messed up the event call somewhere. But reading the events thrown by the model gave exactly the right data. And the values stored in the model would also change as they were supposed to.
Still, the UI refused to update.

I found the solution only after a good nights sleep. While refactoring the model, I accidentally removed the reference to INotifyPropertyChanged:

public class Model : INotifyPropertyChanged
public class Model

Which unfortunately was really hard to notice, because:

  1. The events themselves were still fired, none of that infrastructure was changed
  2. The link between the ComboBox and the TextBlock works without the event as well, just by having them both bind to a plain, simple property

All in all, easy fix, annoying issue.

Leave a comment