Tuesday, August 24, 2010

System.Reactive and Prism RegionContext

What makes them a good match? The complexity of a context assignment!

Your region context comes in a form of an ObservableObject so actually its Value field is null first and then at the moment of your view being bound it will be populated with what you actually setup for it.

ObservableObject<object> context = RegionContext.GetObservableContext(view);

So that takes some of a “synchronization” for a viewmodel to get the context value.

Here is where System.Reactive comes really handy with a single (but long … :):)) line of code:

// In some of the helper classes that have access to a view model while instantiating the view
Observable.FromEvent<PropertyChangedEventHandler, PropertyChangedEventArgs>(
                    (h) => (s, e) => h(s, e),
                    h => context.PropertyChanged += h,
                    h => context.PropertyChanged -= h).
Where(e => e.EventArgs.PropertyName == "Value").
Take(1).Subscribe(eh => viewModel.AssignContext(
                        context));

The intricate part for me was to convert between PropertyChanged handler and EventArgs based handler (that (h) => (s, e) => h(s, e)). Good stuff is Rx taking care of unregistering from the event (Take(1) part) once we encountered it once for a property of the context named “Value” (Where(e => e.EventArgs.PropertyName == "Value"), you can use some reflection based helper to avoid using a string value here).

So far Rx has never translated to me to the less amount of code, but it definitely flattens the complexity (especially when chaining multiple events) and takes care of that event handler unregistering, which is quite good given event handler based memory leak is not the most rare to encounter.

No comments: