Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVVM use of INotifyPropertyChanged Model not notifying ViewModel

I'm trying to use MVVM for the first time. I have a Windows Phone app (Mango), which has a model class, a view model class, and a view xaml page. I have controls (textboxes) bound to the VM, and the VM is bound to the Model.

Both the model and the view model implement INotifyPropertyChanged. The implementation I'm using is copied, so that I could use it to try to figure out what I'm doing with INPC. Here is the code that is listed in both classes:

public event PropertyChangedEventHandler PropertyChanged;

private void NotifyPropertyChanged(String info)
{
   if (PropertyChanged != null)
   {
      PropertyChanged(this, new PropertyChangedEventArgs(info));
   }
}

I have one property in the Model class that can be either set manually (from a textbox) or calculated (by changing one of the other properties). Let's call that one Result.

If I change one of the other properties, and step through, INPC is invoked in both the changed property and the recalculated property in the Model class, although PropertyChanged is null, so that portion of the code is skipped. Then in the VM, the property that was changed steps through that class' INPC (as part of the set accessor), and this time PropertyChanged is not null, so the PropertyChanged method is invoked. For the Result property, however, INPC is not raised (that property doesn't have INPC invoked by the other property's set accessor).

Here is one of the properties in the Model, which is not the calculated property:

public int AgeSetting
{
   get
   {
      return (int)GetValueOrDefault(AgeSettingKeyName, AgeSettingDefault);
   }
   set
   {
      AddOrUpdateValue(AgeSettingKeyName, value);
      Calculate();
   }
}

Here is the property of the Calculated value in the Model.

public int PointsSetting
{
   get
   {
      return (int)GetValueOrDefault(PointsSettingKeyName, PointsSettingDefault);
   }
   set
   {
      AddOrUpdateValue(PointsSettingKeyName, value);
   }
}

From the ViewModel, here are both properties:

public int Age
{
   get
   {
      return person.AgeSetting;
   }
   set
   {
      person.AgeSetting = value;
      NotifyPropertyChanged("Age");
   }
} 

public int PointsAllowed
{
   get
   {
      return person.PointsSetting;
   }
   set
   {
      person.PointsSetting = value;
      NotifyPropertyChanged("PointsAllowed");
   }
}

Having never done this before, I was expecting that INPC should bubble up from the model class, to the VM class, to the UI. It doesn't appear to be working that way.

I know that the Result (calculated) property is changing, as I can navigate away from the page and come back, and the newly displayed value is correct. I just don't know how to get from the calculated value in the model, to the view model, and up to the view.

Thank you for any suggestions.

like image 575
Rich Hopkins Avatar asked Dec 27 '22 14:12

Rich Hopkins


1 Answers

If the value of a calculated property changes, also raise the PropertyChanged event for that property. This means that when a single property changes, there might be events fired for multiple properties.

Also, if it's possible/smart in your design, you could bind directly to model properties and make the Model a property of your ViewModel. This decrease code maintenance by a lot.

like image 169
Bas Avatar answered Jan 14 '23 12:01

Bas