Search code examples
c#wpfmvvmbinding

WPF - PropertyChanged EventHandler not firing


I'm having a problem with subscribing to PropertyChangedEventHandler event of a property on a bound instance of my class.

Here is the setup:

XAML:

<CheckBox IsChecked="{Binding MyObservableClassInstance.BooleanProperty}"/>

DataContext class property:

public MyObservableClass MyObservableClassInstance 
{
    get { return _myClassInstance; }
    set
    {
        _myClassInstance= value;
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("MyObservableClassInstance"));
    }
}

the initialisation and subscription to PropertyChanged event (this subscribed method is never reached):

MyObservableClassInstance = new MyObservableClass();
MyObservableClassInstance.PropertyChanged += OnMyObservableClassPropertyChanged; // <--- This method is never hit

my observable class: (the BooleanProperty is working normally with the the XAML checkbox binding)

public class MyObservableClass : INotifyPropertyChanged
{
    bool _mybool = false;
    
    public event PropertyChangedEventHandler PropertyChanged;

    public bool BooleanProperty
    {
        get { return _mybool; }
        set
        {
            _mybool = value;
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("BooleanProperty")); // <--- This is reached normally on checking/unchecking the checkbox
        }
    }
}

So why is my OnMyObservableClassPropertyChanged method never reached upon Invoking the PropertyChanged event?


Solution

  • You have to attach (and detach) the handler method to the PropertyChanged event whenever the MyObservableClass property value changes.

    public MyObservableClass MyObservableClassInstance 
    {
        get { return _myClassInstance; }
        set
        {
            if (_myClassInstance != null)
            {
                _myClassInstance.PropertyChanged -= OnMyObservableClassPropertyChanged;
            }
    
            _myClassInstance = value;
    
            if (_myClassInstance != null)
            {
                _myClassInstance.PropertyChanged += OnMyObservableClassPropertyChanged;
            }
    
            PropertyChanged?.Invoke(
                this, new PropertyChangedEventArgs(nameof(MyObservableClassInstance)));
        }
    }