I just released some source on Google Code called Observal:


Observal was extracted from work on a recent WPF project. In our application, we had a deep hierarchy of view model objects, with some very complicated interrelationships - setting one property over here means adding or removing items from a collection over there - and since WPF applications are so stateful, we had to do it all reactively.

The project home page gives a simple example of how Observal might be used. I'll use the remainder of this post for a deeper example.


Suppose we have an object model to represent an organization chart:

An employee class, with a collection of direct reports

We'll build a view to show and edit a hierarchy of employees, and provide a filter to show a list of items from the hierarchy:

A window with a treeview of employees, their details, and a list of employees with under $100,000 salary

Working with the hierarchy in WPF is easy - we just build a hierarchical object model and bind it to the tree view. We could build that view model using code like this:

public partial class OrgChartWindow : Window
    public OrgChartWindow()

        var sampleEmployees =
            new Employee("Ryan Howard", 200000,
                new Employee("Michael Scott", 130000,
                    new Employee("Dwight Schrute", 80000),
                    new Employee("Jim Halpert", 80000,
                        new Employee("Andy Bernard", 75000,
                            new Employee("Stanley Hudson", 70000),
                            new Employee("Phyllis Lapin", 70000)))));

        DataContext = new OrgChartViewModel(new[] { sampleEmployees });

That gives us the tree view, ability to add new employees and editing support. But how to we manage the list of employees earning under $100,000?

Enter Observal

The "Employees with salary < $100,000" panel is effectively a flattened view of the employee hierarchy. To build it, we'd need to subscribe to the CollectionChanged event on every employee's DirectReports collection, and to subscribe to the PropertyChanged event on every employee.

Observal makes this trivial. We can make the following addition to our view model:

public OrgChartViewModel(IEnumerable<Employee> employees)
    _rootEmployees = new ObservableCollection<Employee>(employees);

    var observer = new Observer();
    observer.Extend(new TraverseExtension()).Follow<Employee>(e => e.DirectReports);
    observer.Extend(new CollectionExpansionExtension());
    observer.Extend(new PropertyChangedExtension()).WhenPropertyChanges<Employee>(x => FilterEmployee(x.Source));
    observer.Extend(new ItemsChangedExtension()).WhenAdded<Employee>(FilterEmployee);

private void FilterEmployee(Employee employee)
    if (employee.Salary < 100000)
        if (!FilteredEmployees.Contains(employee))

The idea behind observal is that there is an Observer, which keeps a list of items being observed. Observers can accept IObserverExtensions, which are notified when items are added or removed. In the example above, we make use of four different extensions:

  • TraverseExtension - any time an employee is added to the collection, we'll add the DirectReports collection too.
  • CollectionExpansionExtension - when the DirectReports collection is added, we'll add all items in the collection to the observer.
  • PropertyChangedExtension - this is called any time a property on an existing object changes
  • ItemsChangedExtension - this notifies us whenever an item is added or removed

Each extension is useful by itself, but they become very powerful when combined together. In this example, we were able to monitor an entire hierarchy of objects, and to react whenever parts of the hierarchy changes. I'd urge you to check out Observal on Google Code and let me know what you think.

A picture of me

Welcome, my name is Paul Stovell. I live in Brisbane and work on Octopus Deploy, an automated deployment tool.

Prior to founding Octopus Deploy, I worked for an investment bank in London building WPF applications, and before that I worked for Readify, an Australian .NET consulting firm. I also worked on a number of open source projects and was an active user group presenter. I was a Microsoft MVP for WPF from 2006 to 2013.

09 Aug 2010

Cool work, I like it! Thanks!

Mike N
Mike N
11 Aug 2010

I find it annoying having to "roll your own" complex subscription logic - I'm definitely going to give this a try on my own project! (I'm less likely to make mistakes that way)

14 Aug 2010

Great work. Again!!! And nice idea... I'll give it ago once we have more time after this sprint.

I think it's good to go with this simpler approach instead of frameworks like Obtics or another one that I can't remember the name that work really well except for the unsupported scenarios. I'm happy to manually specify my dependencies, but the main hassle is all the event subscription/unsubscription.

T McClean
T McClean
17 Aug 2010

Have you looked at the Reactive extensions (http://msdn.microsoft.com/en-ca/devlabs/ee794896.aspx) from Microsoft dev labs? It seems to be very similar to the concept that you are trying to use here.

17 Aug 2010

Hi T. McClean,

I have looked at Rx, but while they occupy a similar space (reactive programming), they achieve it through very different approaches. Rx doesn't help with ensuring you only subscribe to an event on an object once, or unsubscribing when the object is removed from the collection, and so on. I think Rx is useful for stream-based processing, but not for building stateful views over non-stream object models. That said, if you have an example of how the scenario above could be handled nicely with Rx, I'd love to see it.


22 Oct 2010

Hi Paul,

Looks very nice. I've used Bindable Linq on a project in the past. This seems somewhat related. Did you borrow from blinq for this at all? Do you have any comments on the future of blinq?



22 Oct 2010

One more question... Your examples show cases of self-referencing hierarchies. Does this library help for more general cases where I have, for example, a Purchase Order:

Purchase Order
  Line Items Collection
    Kit Components Collection
      Product Reference 

Could I use Observal in this case somehow to monitor property changes to the line items, kit components, or product reference?