ViewModel subscribing to Model's PropertyChanged event for a specific property

c#, wpf

Solution

The INotifyPropertyChanged interface solves this problem. Subscribe your View Model to the Models PropertyChangedEventHandler and filter your results.

public class ViewModel : INotifyPropertyChanged
{
    ...

    public Model MyModel { get; set; }

    public void methodToBeCalledWhenPropertyIsSet() { }

    public event PropertyChangedEventHandler PropertyChanged;

    public ViewModel()
    {
        // MyModel would need to be set in this example.
        MyModel.PropertyChanged += Model_PropertyChanged;
    }

    private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        if(e.PropertyName == "Property")
        {
             methodToBeCalledWhenPropertyIsSet();
        }
    }
}

In the MVVM pattern the View Model is intended to deal with messy situations like this. This still maintains your abstraction from the model.

Edit As HighCore pointed out, this code doesn't work copy paste. MyModel would need to be instantiated beforehand. I use MEF(http://msdn.microsoft.com/en-us/library/dd460648(v=vs.110).aspx) for this purpose. You can either grab a model class directly or use some kind of factory/manager to get a reference.

Problem

I'd like to have methodToBeCalledWhenPropertyIsSet() execute when Property in the Model is changed. How could I do this? If I understand correctly, I could add `MyModel.PropertyChanged += methodToBeCalledWhenPropertyIsSet` somewhere in my ViewModel to subscribe to the PropertyChanged event in general but I only care when Property is set ``` public class ViewModel : INotifyPropertyChanged { ... public Model MyModel { get; set; } public void methodToBeCalledWhenPropertyIsSet() { } public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } public class Model : INotifyPropertyChanged { object _propertyField; public object Property { get { return _propertyField; } set { _propertyField = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); } } ```

Original source