Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c#

wpf

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));
    }
}
like image 253
William Thomas Waller Avatar asked Jul 09 '14 16:07

William Thomas Waller


1 Answers

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.

like image 196
Daniel Johnson Avatar answered Oct 04 '22 15:10

Daniel Johnson