Refactoring a PropertyChanged Event Handler

    Just a quick code hit I’ve been meaning to blog about … I’ve seen a lot of examples that implement the  PropertyChanged event handler of the INotifyPropertyChanged interface. Most of them are demonstrating how to deal with data binding (including my examples) and most of them simply repeat the code that does the event raising. Some go as far as creating a method that does the raising, too.What I don’t like about the examples that extract a method that does the event raising is that each class would then need to have its own extracted method. Or you could (cringe) put it in a utility class.

    Another solution is to create an extension method. But  sometimes the oldies are the best ways to do things. So here is an example I chose to use in a recent project. I had already created a base class for my entities and named it EntityBase.

    I made the EntityBase implement the INotifyPropertyChanged interface and implemented its single event (PropertyChangedEventHandler) as a virtual event named PropertyChanged.

    Then I created a method in the abstract base class named PropertyChangedHandler (the name is up to you) and its accepts an instance of EntityBase to be used as the sender and the name of the property that is changing.  (see the code below)

    [DataContract]
    public abstract class EntityBase : INotifyPropertyChanged    
    {
        protected void PropertyChangedHandler(EntityBase sender, string propertyName)
        {
            if (PropertyChanged != null)
                PropertyChanged(sender, new PropertyChangedEventArgs(propertyName));
        }
        public virtual event PropertyChangedEventHandler PropertyChanged;  
    }

     

    A class can inherit from the EntityBase (mine already did anyway) and override the event.

    [DataContract]
    public class Product : EntityBase
    {
        public override event PropertyChangedEventHandler PropertyChanged;
    ...
    ...

     

    Finally, here is an example of a property accessor that calls the base class’ protected method PropertyChanged.

    [DataMember]
    public string CategoryName
    {
        get { return _categoryName; }
        set
        {
            _categoryName = value;
            base.PropertyChangedHandler(this, "CategoryName");
        }
    }

     

    The nice thing about this technique is that you just have a single line of code to execute the method in the base class that raises the notification. I wish I could have made the base class’ event abstract, but nothing is perfect.

    You can omit the call to the base class in the code above, too. I just left in the word “base” to make it very clear in the example here.

    If anyone else has any thoughts on better ways or just different ways to handle it, I am interested in hearing your thoughts.

    #1 Jonas on 6.26.2008 at 4:11 PM

    You can use the new partial methods. LINQ to SQL uses them everywhere.

    partial void OnUserIDChanging(int value);

    partial void OnUserIDChanged();

    public int UserID

    {

    get

    {

    return this._UserID;

    }

    set

    {

    if ((this._UserID != value))

    {

    this.OnUserIDChanging(value);

    this.SendPropertyChanging();

    this._UserID = value;

    this.SendPropertyChanged("UserID");

    this.OnUserIDChanged();

    }

    }

    }

    The SendPropertyChanging method raises the event just like you are doing.



    #2 Neil Mosafi on 6.27.2008 at 4:43 AM

    Oooh I wouldn't use Partial Methods for anything which wasn't codegen'd it's way too smelly!

    Anyway another option I can point out is to declare the event as

    public event PropertyChangedEventHandler PropertyChanged = delegate {};

    Then you don't need to worry about checking for null etc because the event cannot be null. Performance hit is pretty minimal for this and you also don't have to worry about concurrency issues etc (which your base class wasn't taking care of).

    Also Seb came up with a good way of doing it using DynamicProxy2 which i thought was very cool and even allows you to use it with automatic properties - serialseb.blogspot.com/.../implementing-in



    #3 Jonas on 6.27.2008 at 12:46 PM

    At first I also thought that partial methods was too smelly, but if you think about it, you don't have to have a partial method for each property. You can have one partial method: OnPropertyChanging or OnPropertyChanged and just call that method on every setter of each property passing in both the propertyname and the value. In that case it wouldn't required a lot of code and thus no need for autogenerated code.

    Performance wise I'm not sure which way is better.



    #4 John Papa on 6.27.2008 at 6:27 PM

    I agree that in this case I would not use partial methods. Not when there are alternatives like a base class method. But its an idea I had not thought of.



    Leave a Comment