Advanced property change notifications

by Geert 21. October 2011 16:10

Sometimes the old value is needed in case of property change event. However, the INotifyPropertyChanged interface does not provide any of this. To support this behavior, a new version of the PropertyChangedEventArgs is created called AdvancedPropertyChangedEventArgs. This class derives from PropertyChangedEventArgs so the interfaces are not broken, but it does add additional functionality to the software system.

In Catel 2.3, the change notification system is updated. This means that it is now possible to actually get more information about a property change, such as the old value and the new value.

Getting old value automatically

When using the DataObjectBase or ViewModelBase classes, the old and new value of a property are automatically provided on a property change. There are two ways to get more information about a property change event.

Getting more information from the inside

The easiest way to get more information on the inside is to override the OnPropertyChanged method. It automatically provides an instance of the AdvancedPropertyChangedEventArgs:

   1: protected override void OnPropertyChanged(AdvancedPropertyChangedEventArgs e)
   2: {
   3: }

Getting mode information from the outside

Getting the information from outside the objects is a bit more work. This is because the PropertyChanged event still provides a value of the PropertyChangedEventArgs class. Therefore, it is required to cast the value:

   1: private void OnObjectPropertyChanged(PropertyChangedEventArgs e)
   2: {
   3:     var advancedArgs = e as AdvancedPropertyChangedEventArgs;
   4:     if (advancedArgs != null)
   5:     {
   6:         // a value of AdvancedPropertyChangedEventArgs is now available
   7:     }
   8: }

Providing old value manually

When using the dependency property a-like property registration, the old and new value are automatically provided by the classes. However, when using the ObservableObject, the old and new value are not automatically provided. Therefore, it is possible to provide these values manually:

   1: private string _firstName;
   2:  
   3: public string FirstName
   4: {
   5:     get { return _firstName; }
   6:     set 
   7:     { 
   8:         var oldValue = _firstName;
   9:         _firstName = value;
  10:  
  11:         RaisePropertyChanged(() => FirstName, oldValue, value);
  12:     }
  13: }

When the values are not provided, the old and new value are set to null.

Some sidenotes

As you might have noticed, the AdvancedPropertyChangedEventArgs also provide the IsOldValueMeaningful and the IsNewValueMeaningful. These are introduced because it is not always possible to determine the old or new value (for example, when the property name is string.Empty, there is no old value or new value). Therefore, the OldValue and NewValue properties are null, but doesn't mean that those are the actual old and new values.

It is always required to check whether the values are meaningful before actually handing them:

   1: protected override void OnPropertyChanged(AdvancedPropertyChangedEventArgs e)
   2: {
   3:     if (e.IsOldValueMeaningful)
   4:     {
   5:         // Handle old value
   6:     }
   7:  
   8:     if (e.IsNewValueMeaningful)
   9:     {
  10:         // Handle new value
  11:     }
  12: }

Tags:

Catel | C#

Comments are closed

About the Author

Geert van Horrik is an independent freelance software developer since January 1st, 2007. Since then he was been working on several projects from C++ to C# (WPF, Silverlight, ASP.NET, etc). Currently he loves to write his software using WPF (or Silverlight if WPF isn't an option).

Lately, Geert is spending a lot of time on Catel, a free open-source MVVM Framework for WPF and Silverlight. Actually, it's more than "just" an MVVM Framework, it's a complete application library!