Type-safe INotifyPropertyChanged and derived classes

Some of you who read my previous blog post notice that this technique doesn’t allow to raise “PropertyChanged” event from a derived class. This is because you can only call method of “PropertyChangedEventHandler” from the class where it is defined. Anywhere else you can only assign (+=) and unassign (-=) event handler.

One way to work around this is to add a method in your base model class that will forward the call to “PropertyChangedEventHandler”.

Here is a modified copy of the class from my previous post:

Now you can define a derived class and use the same method to raise a PropertyChanged event.

Now with very little effort you can build a type-safe and bindable data model.

It is also useful to be able to raise many property at once. For example if have calculated properties that depends on others like in this sample class:

Because a change to either “FirstName” or “LastName” should trigger a change to “FullName” you have to raise both changes from both properties. Of course you can call “RaisePropertyChanged” many times but with a simple overload you can do this. All you have to do is add this to your extensions class.

Aside from beeing type safe, this method will give you intellisense support while you type your “RaiePropertyChanged” calls. You still have to type the right property though.


3 thoughts on “Type-safe INotifyPropertyChanged and derived classes

  1. @Rick
    Someone posted the solution:
    http://blog.decarufel.net/2009/07/how-to-use-inotifypropertychanged-type_22.html
    Quote Stefan Lange:
    Very good idea! After I tried it out I have two hints:

    If the property is a value type you need an additional step to unbox the expression body:

    ((MemberExpression)((UnaryExpression)propertyExpression.Body).Operand).Member.Name

    The only reason why you must compile and execute the expression is to retrieve the sender. I would avoid this completely by simply adding the sender to the parameters:

    PropertyChanged.Raise(this, () => Data);

    I think adding the sender is better than creating code to retrieve it.

  2. I’m trying to implement this and one boolean property is causing a property expression should be a member expression error. When I break on if (body — null), body is null, but if I highlight propertyExpression.body in quick watch it returns the lambda… Very strage but prevents it from working. Any ideas?

Leave a Reply