Wpf – Good way to refresh databinding on all properties of a ViewModel when Model changes

data-bindinginotifypropertychangedmvvmwpf

Short Version

If I update the Model object that my ViewModel wraps, what's a good way to fire property-change notifications for all the model's properties that my ViewModel exposes?

Detailed Version

I'm developing a WPF client following the MVVM pattern, and am attempting to handle incoming updates, from a service, to data being displayed in my Views. When the client receives an update, the update appears in the form of a DTO which I use as a Model.

If this model is an update to an existing model being shown in the View, I want the associated ViewModel to update its databound properties so that the View reflects the changes.

Let me illustrate with an example. Consider my Model:

class FooModel
{
  public int FooModelProperty { get; set; }
}

Wrapped in a ViewModel:

class FooViewModel
{
  private FooModel _model;

  public FooModel Model 
  { 
    get { return _model; }
    set 
    { 
      _model = value; 
      OnPropertyChanged("Model"); 
    }
  }

  public int FooViewModelProperty
  {
    get { return Model.FooModelProperty; }
    set 
    {
      Model.FooModelProperty = value;
      OnPropertyChanged("FooViewModelProperty");
    }    
}

The Problem:

When an updated model arrives, I set the ViewModel's Model property, like so:

instanceOfFooVM.Model = newModel;

This causes OnPropertyChanged("Model") to fire, but not OnPropertyChanged("FooViewModelProperty"), unless I call the latter explicitly from Model's setter. So a View bound to FooViewModelProperty won't update to display that property's new value when I change the Model.

Explicitly calling OnPropertyChanged for every exposed Model property is obviously not a desirable solution, and neither is taking the newModel and iterating through its properties to update the ViewModel's properties one-by-one.

What's a better approach to this problem of updating a whole model and needing to fire change notifications for all its exposed properties?

Best Answer

According to the docs:

The PropertyChanged event can indicate all properties on the object have changed by using either null or String.Empty as the property name in the PropertyChangedEventArgs.

Related Topic