Randolph Cabral’s Weblog

…beauty is just a dimmer switch away…

Archive for October, 2009

Raising INotifyPropertyChanged Events with an Extension Method

Posted by Randolph Cabral on Friday, October 2, 2009

Okay, I’m probably not the only one out there that is tired of writing the NotifyPropertyChanged() method in all my entity and ViewModel classes.  And I’m probably not the only one who is afraid of magical strings. So today, I’m posting a simple reusable extension method that targets all classes that implement the INotifyPropertyChanged interface.  And while we’re at it, why not take advantage of lambda expressions to give us the benefit of Visual Studio’s intellisense/automatic code completion features as well.

Take 1 : The Way It Is

Let’s start with the standard implementation of the INotifyPropertyChanged interface. The following should look familiar. Notice that each setter has a call to the NotifyPropertyChanged() method which needs a magic string to pass to the event args.  Careful! If you misspell or mis-case the magic string, you’re gonna get smacked with a runtime exception if you aren’t paying attention. If you’re into that sort of thing, you should probably find professional help.

    1   public class Camel : INotifyPropertyChanged
    2   {
    3     private int _Age;
    4     public int Age
    5     {
    6       get
    7       {
    8         return _Age;
    9       }
   10       set
   11       {
   12         _Age = value;
   13         NotifyPropertyChanged("Age"); //What's with the magic strings?
   14       }
   15     }
   16
   17     private string _Name;
   18     public string Name
   19     {
   20       get
   21       {
   22         return _Name;
   23       }
   24       set
   25       {
   26         _Name = value;
   27         NotifyPropertyChanged("Mane"); //This may result in a runtime exception.
   28       }
   29     }
   30
   31     private bool _HasGingivitis;
   32     public bool HasGingivitis
   33     {
   34       get
   35       {
   36         return _HasGingivitis;
   37       }
   38       set
   39       {
   40         _HasGingivitis = value;
   41         NotifyPropertyChanged("HasGingivitis");
   42       }
   43     }
   44
   45     //Do I really need to write this method for all of my classes?? I'm too lazy.
   46     private void NotifyPropertyChanged(string propertyName)
   47     {
   48       if (null != PropertyChanged)
   49         PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
   50     }
   51
   52     #region INotifyPropertyChanged Members
   53
   54     public event PropertyChangedEventHandler PropertyChanged;
   55
   56     #endregion
   57   }

Take 2 : The Way I Want It To Be

Now let’s look at a sample using the extension method implementation. With this implementation our beloved magic strings are replaced with intellisense-friendly lambda expressions. Notice that the calls to the extension method requires the use of ‘this.’ syntax. Additionally, the extension method needs a reference to the delegate in order to fire the event.

    1   public class Camel : INotifyPropertyChanged
    2   {
    3     private int _Age;
    4     public int Age
    5     {
    6       get
    7       {
    8         return _Age;
    9       }
   10       set
   11       {
   12         _Age = value;
   13         this.NotifyPropertyChanged(e => e.Age, PropertyChanged);
   14       }
   15     }
   16
   17     private string _Name;
   18     public string Name
   19     {
   20       get
   21       {
   22         return _Name;
   23       }
   24       set
   25       {
   26         _Name = value;
   27         this.NotifyPropertyChanged(e => e.Name, PropertyChanged);
   28       }
   29     }
   30
   31     private bool _HasGingivitis;
   32     public bool HasGingivitis
   33     {
   34       get
   35       {
   36         return _HasGingivitis;
   37       }
   38       set
   39       {
   40         _HasGingivitis = value;
   41         this.NotifyPropertyChanged(e => e.HasGingivitis, PropertyChanged);
   42       }
   43     }
   44
   45     #region INotifyPropertyChanged Members
   46
   47     public event PropertyChangedEventHandler PropertyChanged;
   48
   49     #endregion
   50   }

Where the Magic Happens

Here’s the implementation for the extension method.  It’s pretty straightforward and self-explanatory so I’ll save you the time and just leave it at that. Have fun with it!

    1 namespace Extensions
    2 {
    3   public static class ExtensionMethods
    4   {
    5     public static void NotifyPropertyChanged<TEntity>(this TEntity entity,
            Expression<Func<TEntity, object>> propertySelector,
            PropertyChangedEventHandler propertyChanged)
    6       where TEntity : INotifyPropertyChanged
    7     {
    8       if (propertyChanged != null)
    9         propertyChanged(entity,
                new PropertyChangedEventArgs(FormatPropertyName(propertySelector)));
   10     }
   11
   12     static string FormatPropertyName<TEntity>
            (Expression<Func<TEntity, object>> propertySelector)
   13     {
   14       var memberExpression = propertySelector.Body as MemberExpression;
   15       return memberExpression.Member.Name;
   16     }
   17   }
   18 }

Posted in C#, ComponentModel, Extension Methods, INotifyPropertyChanged | 1 Comment »