RSS
 

Stream an INotifyPropertyChanged property’s values through an IObservable

12 Nov

One of the new .NET technologies that is really exciting to me these days is the Reactive Extensions to .NET (RX). Sometimes it’s called LINQ to Events, because you can write LINQ queries against future values (events, nicely wrapped up into the IObservable<T> interface), instead of against existing collections (IEnumerable<T>). This technology is especially useful in stateful programming models, such as when you’re building ViewModels for WPF or Silverlight. Once you start programming with RX (although it’s got a steep learning curve!), you start to see lots of places where it would really help make your code simpler. I saw one such place: whenever you need to programatically respond to an INotifyPropertyChanged notification.

INotifyPropertyChanged

INotifyPropertyChanged is an interface that most viewmodels need to implement. It’s used implicitly by the Silverlight and WPF data binding system to register a databinding’s interest in the fact that a property has changed, thus keeping all bindings to the same property up to date. When you implement it, you’re responsible for firing a PropertyChangedEvent event every time a property changes, with the name of the property as a parameter to the event.

Sometimes, you might want to programatically watch changes to a property too. Imagine a screen where users can add rows of data that represent orders. If there needs to be a “grand total” on the screen, then one viewmodel (possibly the root VM for the whole screen) will want to subscribe to the PropertyChanged event of each of the order’s Viewmodels. However, there’s a nicer programming model for listening to updates (events etc) than the INotifyPropertyChanged event…

IObservable

IObservable is the core of all RX programming (like IEnumerable is to LINQ). If you want to expose a source of data, you need to expose an IObservable. There’s already a utility method to turn an event into an IObservable. But this Observable will publish IEvents, which isn’t quite what I was after. What I wanted was to create an IObservable of the new values of the viewmodel’s property. Just like LINQ, we can use the “Select” method to acheive this.

Funcy Expressions

An Expression is a C#3 construct that allows you to pass expression trees around. This is a very popular way for you to strongly type property names, because you can reflect over an Expression> to get the name of the Property. You can also Compile() the expression to be able to execute it. My method uses both of these: It needs to know which PropertyChangedEvents it should react to (the Where() clause), and it needs to read the new value out (the Select() clause).

The tests

Here are the unit tests for this extension method. I had to create a dummy view model class to test, named “PropertyChanger”. Note how you can supply “true” to the startWithCurrent parameter to make sure your subscription will instantly start with the current value of the property, as well as receiving new values whenever a PropertyChangedEvent is fired.

Enjoy!

 

Tags: , ,

Leave a Reply