INotifyPropertyChanged… I am fed up of handling events just to know when a property changed

The INotifyPropertyChanged is what tells the WPF/SL binding that a property changed and that the binding should be updated. For this purpose its quite good. But what many times we end up doing is; handling the PropertyChanged in code so that we get notified that a property changed. An example is a ViewModel that need to know when a property in the underlying model changed and if it did it will do something to facilitate the View.

Doing this in code is a bit ugly because you base everything on “magic strings”.. something like this

image

Another problem is that if you use an anonymous delegate you need to do loads of tricks in order to unregister to the event.

In order to over come this I created a PropertyObserver that handles these 2 issues. (Please note that there are already others, Philip Sumi has a good one here and  Josh Smith has a good one here. I created my own since I wanted to have extra + different way of doing it). Also this problem can be solved easily using Rx, I am doing this sample so that you do not need to depend on Rx.

The implementation I did is very simple, I created a PropertyObserver class that uses lambdas so that you tell it what property you want to subscribe to and pass an action to do your “Property Changed handling”. What I also did is an attached method so that all objects that implement INotifyPropertyChanged can simple handle the property changed… so the code looks like this

image

One would ask and how do I unregister? is this using weak event pattern? The answer is NO. I wanted to keep it simple and cross platform (for WPF and SL). what you can do is a more Rx approach… basically in RX if you subscibe to something you get an IDisposable in return so that you can Dispose (i.e in our case unsubscribe) when you want like this

image

as you can see here I am wrapping the call in a using statement… but if you need to unsubscribe in any specific state you can store the IDisposable that you get from the Do call and call Dispose to unsubscribe.

Many times you need this for only one time i.e a property changes you do something and you do not want to get called any more times. For this I created a DoOnce. This will unsubscribe for you once the property changes once. The API is very similar and looks like this

image

That’s more or less it.

Big thanks go to Diego Colombo and John Rayner (two champs that work with me) for the help and input they gave me on this :) You rock guys!

You can download the code here.

OR if you have MEFedMVVM download the latest version since its in MEFedMVVM.

About these ads

9 thoughts on “INotifyPropertyChanged… I am fed up of handling events just to know when a property changed

  1. Have you checked out the ReactiveObject that comes with Continuous LINQ? I find that very useful, though it’s more aimed at dependencies that last for the duration of your object’s lifetime rather than DoOnce. Also I don’t know how Silverlight- friendly the implementation is.

  2. Pingback: Dew Drop – May 30, 2010 | Alvin Ashcraft's Morning Dew

  3. This is a very nice solution to an old problem. I like the fact that it doesn’t implement weak referencing, and still maintains control over unregistering the event when using lambdas/anonymous delegates.

    One suggestion: It is often the “Do” code that knows when to unregister – what about giving the IDisposable reference as a parameter to the Do-lambda?

  4. >> “It is often the “Do” code that knows when to unregister – what about giving the IDisposable reference as a parameter to the Do-lambda?” that should be quite easy to do. the one quetion I have is can you give me an example

    • I see your point Marlon – my bad. I was thinking in terms of general event handling. For the PropertyChangedEvent you want it either once or all the time.

  5. Pingback: INotifyPropertyChanged… I am fed up of handling events just to know when a property changed

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s