MVVM: Modified model, how to correctly update ViewModel and View?
c#, domain-driven-design, mvvm, prism, silverlight
Solution
If the view is binding to the Model directly then as long as the service is using the same instance any changes to the model properties will be propogated to the view.
However if you are recreating a new model in the service then you will give the viewmodel the new model. I expect to see the model as a property on the view model so when you set that property all binding should be alerted to the change.
//in the ViewModel
public Person Model
{
get { return _person; }
set { _person = value;
RaisePropertyChanged("Model"); //<- this should tell the view to update
}
}
EDIT:
Since you state there are specific `ViewModel` logic then you can tailor those properties in the `ViewModel`
private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName == "Prop1") RaisePropertyChanged("SpecicalProperty");
...
}
public string SpecicalProperty
{
get
{
reutrn Model.Prop1 + " some additional logic for the view";
}
}
IN XAML
<TextBlock Text="{Binding Model.PropertyDirect}" />
<TextBlock Text="{Binding SpecicalProperty}" />
This way only both the `Model` and `ViewModel` propertys are bound to the view without duplicating the data.
You can get fancier creating a helper to link the property changes from the model to the view model or use a mapping dictionary
_mapping.Add("Prop1", new string[] { "SpecicalProperty", "SpecicalProperty2" });
and then find the properties to update by getting the list of properties
private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
string[] props;
if(_mapping.TryGetValue(e.PropertyName, out props))
{
foreach(var prop in props)
RaisePropertyChanged(prop);
}
}
Problem
Case Say I have a `Person` class, a `PersonViewModel` and a `PersonView`. Updating properties from `PersonView` to the `Person` model is simple enough. `PersonViewModel` contains a `Person` object and has public properties the `PersonView` binds to in order to update the Person model. However. Imagine the `Person` model can get updated by `Service`. Now the property change needs to be communicated to the `PersonViewModel` and then to the `PersonView`. This is how I would fix it: For each property on the `Person` model I would raise the PropertyChanged event. `PersonViewModel` subscribes to the PropertyChanged event of `Person`. `PersonViewModel` would then raise another PropertyChanged in order to update the `PersonView`. This to me seems the most obvious way but I kind of want to throw this question out there in the hope of someone showing me a nicer way. Is it really this simple or are there better ways to mark the model as modified and update the respective properties on the ViewModel? Additions The `PersonView`'s DataContext is `PersonViewModel`. `Person` gets populated from JSON and gets updated many times during its lifetime. Feel free to suggest architectual changes for my particular case. Answer I marked aqwert as the answer of my question since it provided me with an alternative to the solution I already proposed.