Doing GUI architecture the Right Way

WPF binding is great, but directly binding the View to the Model has its limitations. As soon as the Model’s and the View’s structure diverge (which happens quite fast, I was surprised myself) the direct binding approach falls apart. The first example where I hit this was a tree of items which should be displayed and selected in a (decorated) list. Data binding just doesn’t cut it. The solution lies in creating a so called ViewModel.

The ViewModel

The ViewModel acts as an Adapter between the View and the Model. A very intelligent Adapter. It contains all logic, properties and events to allow a “trivial” View implementation. This provides for a clear separation of concerns:
  • the Model as data store
  • the View as vehicle for actual user interaction, that is drawing pixels and receiving input events
  • the ViewModel to transform the data into view-specific structures, translate manipulation of these structures back into the Model and hold view-specific state

Example

A simple example for a ViewModel (or Presenter Model, as it called in the Composite Application Guidance for WPF) is the CollectionView used as Adapter between the ListBox and a collection.
You can think of a collection view as a layer on top of a binding source collection that allows you to navigate and display the collection based on sort, filter, and group queries, all without having to manipulate the underlying source collection itself. If the source collection implements the INotifyCollectionChanged interface, the changes that raise the CollectionChanged event are propagated to the views.

Benefits

One of the nice effects of a ViewModel is the ability to share such a model, giving instant synchronisation between multiple Views. This works because the individual Views do not have any state, but are completely dependent on the ViewModel. Another subtle but nice point is the massive reduction in imposed structure on the View. Only a single, light-weight injection interface is needed to give the View access to the ViewModel. This allows more flexibility in evolving the ViewModel, since only breaking changes affect all Views. On the other hand, Views can incrementally support more and more features of a given ViewModel without having to pay big up-front costs in implementing/stubbing a huge interface. In the same vein, the ViewModel has no dependency of the View in any kind, which makes the ViewModel the ultimate lookless control. Automated testing became a big topic over the last years and the ViewModel follows the trend by being very easy to test. To test a presenter/controller in a MVP or MVC architecture, both the View and the Model have to be replaced for a test. Since a View of a ViewModel shouldn’t contain any “real” code, testing can concentrate on the functionality of the ViewModel and only mock up the Model, something which is needed for most tests of components using the Model anyways. Last (but perhaps not least) is a purely aesthetic point: All dependencies in a ViewModel architecture point in the same direction. The Model works with a data source, the Business Logic works with the Model, the ViewModel works with the Business Logic and the Model, and the View only works with the ViewModel. This enables the uniform re-use of the same mechanisms and patterns — Validation, Transactions, Change Notification, etc — over the various levels of the application.

Conclusion

ViewModels represent the current top of the evolution in lookless controls. By combining data binding and the programmatic power of a Presenter/Controller component into a single concept without dependencies on a specific View technology, they provide a high degree of flexibility in representing the internal state of an application without getting bogged down in the intricate details of designing a great user experience. I’m already thrilled how this will work out in more complex scenarios. And what’ll come next :-)

dasZ.at

dasZ.at - the people behind ZBox.
dasZ.at Logo

Downloads

The lateset download will be available here - soon

Lastet blog

In our blog we talk about the latest developments around our tool ZBox.
>> Blog

Latest blog entries
>> Reference project: Implementing WordPress-based Website

Based on the reference design provided by Sabine herself, we implemented the zartbitter Website. The site is powered by the PHP-based WordPress blog and CMS engine, some additional plugins and a bit of yarn to hold it all together.


>> Setting a permanent search_path, the Right Way

Others recommend setting the search_path in the postgresql.conf. Current versions of PostgreSQL can set the search_path permanently on a per-database basis without having to touch system configuration files


>> Porting Puppet to Windows

In the course of the PuppetCamp Europe, I met with many people I only knew from IRC and email and it was a great time with interesting and inspiring discussions.

Today I want to write about the work I’m currently commisioned for by puppetlabs, porting puppet to Microsoft Windows.


>> Puppetcamp Europe 2010

I’m going to Puppetcamp Europe 2010!


>> Using gendarme with Code Contracts from .NET 4.0

When using gendarme on post-processed assemblies with code contracts and /throwonfailure set, a few things have to be ignored. Put the following lines into your ignore file (for example gendarmeignore.txt) and use it with –ignore on the command line.


>> Microsoft cannot decode Base64: News at 11!

Arthur has found a really nasty bug in Microsoft’s streaming Base64 decoder as used in the WCF: Connect Bug#541494


>> Kolab Connector binaries uploaded

Arthur moved on with programming and testing. Now we uploaded the first packages, which now contain the basic calendar and contacts synchronisation. The plugins already are able to synchronize our personal data.


>> Kolab Sync for Android and Outlook: Developer Preview

We are proud to announce the first developer preview for Kolab sync clients for both Android and Outlook. Both are licensed under the GPLv3.


>> Visual Studio 2008 Debugger

I didn’t know that: the VS2008 debugger has many bugs. Specifically, if you have a solution with multiple websites, debugging doesn’t work!

Symptom: Upon reaching a breakpoint, StepOver/Into do not work, but resume execution. This makes the debugger pretty pointless.


>> Building a simple MSBuild Task

On the “Using Studio’s “Custom Tool” in MSBuild” question, I was prompted to share the code. Here is a stripped down skeleton where I removed the actual calls to the custom tool. Since it is open source I didn’t really need to access the Visual Studio’s registry keys.