Aug 172009
 

When working with Silverlight two-way binding (and not only there) you need to implement the INotifyPropertyChanged interface in order to notify any observers that the property values of the object have changed.

The INotifyChangedProperty exposes only the PropertyChanged event which is used by observers to subscribe to the change notifications. The typical pattern is to have a base class which will fire the events like this:

   1: public abstract class PropertyChangedNotifier : INotifyPropertyChanged

   2:    {

   3:        protected virtual void OnPropertyChanged(string propertyName)

   4:        {

   5:            var eventHandler = PropertyChanged;

   6:            if (eventHandler != null)

   7:            {

   8:                eventHandler(this, new PropertyChangedEventArgs(propertyName));

   9:            }

  10:        }

  11: }

This can be used like this:

   1: public class MyClass

   2: {

   3:     private string myProperty;

   4:     public string MyProperty

   5:     {

   6:         get { return myProperty; }

   7:         set

   8:         {

   9:             if(myProperty != value)

  10:             {

  11:                 myProperty = value;

  12:                 OnPropertyChanged("MyProperty");

  13:             }

  14:         }

  15:     }

  16: }

For small projects, this implementation is ok, but on large scale projects, using such an implementation will lead to a maintenance nightmare, especially when performing property rename refactorings. After each refactoring, you need to manually change the name of the property inside the setter.

Type safe implementation using Expression Trees

.NET 3.5 comes with the ability of navigating through the object hierarchy using Expression trees. This is used for example in LINQ providers for dynamically building the SQL queries. The same Expression trees can be used in this case for building a type safe solution for the OnPropertyChanged method:

   1: public abstract class PropertyChangedNotifier : INotifyPropertyChanged

   2: {

   3:    protected virtual void OnPropertyChanged<T>(Expression<Func<T>> action)

   4:    {

   5:        var propertyName = GetPropertyName<T>(action);

   6:        OnPropertyChanged(propertyName);

   7:    }

   8:

   9:    protected static string GetPropertyName<T>(Expression<Func<T>> action)

  10:    {

  11:        var expression = (MemberExpression)action.Body;

  12:        var propertyName = expression.Member.Name;

  13:        return propertyName;

  14:    }

  15:

  16:    public event PropertyChangedEventHandler PropertyChanged;

  17: }

Coming back to the class example above, the new type safe implementation can be used as below:

   1: public class MyClass

   2: {

   3:     private string myProperty;

   4:     public string MyProperty

   5:     {

   6:         get { return myProperty; }

   7:         set

   8:         {

   9:             if(myProperty != value)

  10:             {

  11:                 myProperty = value;

  12:                 OnPropertyChanged(()=>this.MyProperty);

  13:             }

  14:         }

  15:     }

  16: }

Conclusion

In this blog article I have presented a way of implementing a type-safe notifier for the INotifyPropertyChanged interface. The implementation presented here uses expression trees for achieving this.

I haven’t tested the performance overhead of using expression trees, but I guess if this is an issue, you can easily cache the results for further usage.