A Field Guide to WPF Presentation Patterns

I have seen some confusion around the naming of the major UI presentation patterns, often with code being described as one pattern when actually it uses a different one. This usually happens because the goals behind each pattern are similar and the descriptions are a little too theoretical. I want this page to serve as a practical description of each pattern and to provide some concrete examples of what differentiates the patterns in the wild.

The Three Major UI Patterns

The three UI patterns commonly used in WPF applications are Model-View-Controller, Model-View-Presenter and Model-View-ViewModel (MVC, MVP and MVVM respectively).

Model View Controller

MVC was the original pattern, but the description of the pattern and the reality of how it is used have evolved. Fowler's page on the subject describes a controller as co-ordinating the behavior of a view, as if there were one controller per view. From the original Smalltalk MVC paper:

Each view is associated with a unique controller and vice versa

By that definition, we should expect controllers to look like this, with each controller clearly associated with one and only one view:

public class EditCustomerController : Controller<EditCustomerView>

Anyone who has used a web based MVC framework, however, has seen a very different style of implementing MVC. The success of recent MVC frameworks like Ruby on Rails, ASP.NET MVC and Zend have changed the working definition of MVC to a controller that handles many views. Controllers in this style typically look like:

public class CustomerController : Controller
{
    public ActionResult List();
    public ActionResult Show(int customerId);
    public ActionResult Edit(int customerId);
    public ActionResult Save(Customer customer);
    public ActionResult Delete(int customerId);
}

Where each of the actions return a different view.

I think there is an argument to be made that Zend, ASP.NET MVC and Rails aren't actually MVC, because Controllers deal with multiple views, when the original definition clearly said they should be unique. But that's only at design time - at runtime, when a request is received, the controller typically only creates one view per request, so perhaps it does meet the definition. It's a very blurry line that I'm not sure I want to get in the middle of.

Either way, MVC has come to mean a controller that handles many requests for different views, so that's the definition I use. Controllers tend to focus on navigation between views, rather than long-running interactions with a single view. Magellan has this focus.

Model View Presenter

MVP is described as a derivative of MVC. But when you see working examples of MVP, they tend to look just like the original definition of MVC, with a unique presenter per view. WebFormsMVP is an framework for this for ASP.NET. Caliburn is an MVP framework for WPF. I've also posted an example of building your own for WPF.

MVP has been further split into two approaches - Supervising Controller and Passive View. Supervising Controller is the version that almost everyone uses, and closely matches the original MVC definition. Passive View provides even more testability, and would be possible in WPF by exposing every Routed Event and the controls directly to the presenter, but I have never seen it implemented in WPF (and I don't think I would want to).

MVP in the form of Supervising Controller looks extraordinarily similar to MVC. The major difference is suggested in this snippet on Supervising Controller:

For input response the controller operates in the presenter style. The user gestures are handled initially by the screen widgets, however all they do in response is to hand these events off to the presenter, which handles all further logic.

This is the critical difference. In MVC, the controller gets the event first, before the view does. In MVP, the view gets the event first and gives it to the presenter.

On the web we can see how that works - user input happens in the form of HTTP requests, so controllers handle those and then render the view. But in WPF, controls always accept the user input first - the controller can never handle the input before the view.

Model View ViewModel

Fowler described this as the Presentation Model pattern, but WPF and Silverlight developers have come to know it as the MVVM pattern thanks to a John Gossman article. The Wikipedia article on MVVM has the history, but basically, MVVM is a specific example of Presentation Model in WPF and Silverlight applications. Personally, I use it because the first two patterns start with "MV" so the third may as well too.

MVVM is similar to MVP, but the ViewModel contains both state and behavior, while in MVP the state is generally kept in the model. The other major difference is that in MVP, where the Presenter references the View and can tell it what to do, in MVVM the ViewModel doesn't reference the View - instead, the ViewModel exposes properties and raises events that the View subscribes to.

Summary of Patterns

  • Model View Controller: Controller is concerned with navigation, and handles requests for many views. Controller typically creates the view and forgets about it. Controller gets user input before view.
  • Model View Presenter: Presenter is concerned with a single View. The presenter and view have a meaningful conversation. Model holds state, presenter contains behavior. View gets user input and passes to presenter.
  • Model View ViewModel: Much like MVP, but ViewModel contains both state and behavior. The ViewModel shouldn't have a reference to the View.

Identifying the Patterns

When you build a framework or spot some code, here are some concrete things to look for to identify the pattern. I'll use the term co-ordinator to refer to the third object in each pattern (Controller, Presenter or ViewModel).

  • If the co-ordinator has a reference to the view, you might be using MVP.
  • If the view is bound to properties on the co-ordinator, or the co-ordinator is the DataContext of the view, you might be using MVVM.
  • If the co-ordinator deals with navigation between multiple views, you might be using MVC.
  • If the view calls methods on the co-ordinator, you might be using MVVM.
  • If the view has to pass user input events to the co-ordinator, you might be using MVP.

Smalltalk-style MVC is impossible in WPF

As described above, in MVC, the controller gets input first, before the view. In MVP, the UI gets the input, and forwards it to the presenter.

An example is MVC4WPF. Controllers in MVC4WPF are associated with a single view and typically look like:

public class CustomerController : WPFViewWindowControllerBase<ICustomerView>

This looks similar to the Smalltalk type of MVC. But when I click a button, the view forwards that event to the controller. Based on the Supervising Controller definition above, this is really MVP, not MVC. The only way to achieve this style of MVC in WPF would be to have the controller handle events before the view - impossible with WPF.

A picture of me

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

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.

Rob
Rob
14 Jan 2010

Another good post! Thanks for pointing out that Smalltalk MVC is impossible with WPF. That's something I've been trying to explain to people when I discuss presentation patterns. The tricky part about patterns is that they are contextual and their implementation can look quite different depending. MVC looks different on Smalltalk, on WPF and on the Web (though I think Magellan does an incredible job keeping its API similar to ASP.NET MVC), but the spirit of the pattern is the same. WPF shakes things up a bit because of its extreme databinding capabilities. So, I think that it can sometimes be hard to classify a class as MVP or VM in certain (not all) scenarios.

It's also important to note that different application styles or different features work better with different presentation patterns. So, while you may favor MVP for the application's general architecture, there may be silos within your app that make more sense with MVC or MVVM. Trying to force everything (even within the same app) into a single pattern can actually result in over-complication. Though you should strive for architectural consistency, its good to keep one's mind open to alternative solutions.

14 Jan 2010

I agree with Rob; this was a terrific post! However, I disagree that Smalltalk-style MVC is impossible, though it is likely not worth the effort. Smalltalk-style MVC works because Smalltalk ran on a VM with which the code could interact at runtime. That's very similar to the way the web works--all of your actions are running in the environment and being passed back to the controller. A naive approach to this might be to build your own XAML viewer and have all UI events handled by the viewer, which would then pass them to the route.

I'm getting closer to a much nicer approach using Attached Events (gotta love bubbling), MEF, Reactive Extensions, and extension methods. I'm hoping to release a small preview soon, but I've still got a bit of work to make it look interesting. I'd be glad of any feedback, especially thoughts as to whether or not I'm actually achieving Smalltalk-style MVC. I'm using my Shell as my "environment." I'm thinking that since it is taking the events and passing them along to the controller, this is escaping the view-first of MVP, but I could just be deceiving myself. :)

Cheers!

15 Jan 2010

@Rob, that's an important point. Often architects like to dictate that pattern A or pattern B should be used for building the UI. It often works better if you don't limit developers to a single pattern, and instead just provide guidance on when and how to use each.

@Ryan, impossible was probably a bad word, since anything is possible if you have enough time - a way I thought of doing it was to have the controller handle the Win32 message queue, though that's getting a little ridiculous :) It was really just a tool to highlight the MVP/MVC difference and point out that when looking at code, it's probably more likely to be MVP than MVC. I can't wait to see your approach to Smalltalk-style MVC for WPF.

16 Jan 2010

Nice post. I think the confusion with MVC is that with most patterns, there is often an entry-level pattern that then puts you in a position to apply more sophisticated versions of the pattern.

For example, it could be argues that code behind in classic ASP.NET is an example of MVC because all of the events are scoped to the code behind and the code behind is a controller for a single view (the aspx page). Now of course, many developers will sling ADO.NET code in the code behind but this is due more to laziness or lack of experience than anything else.

The next evolution from there is what you describe and what I agree seems to be the most common definition of MVC: the page controller.

What I think we are seeing in ASP.NET is the big brother of MVC: the Front Controller.

This causes confusion for folks jumping right into MVC because it is an advanced flavor of MVC and I think posts like yours go a long way in explaining the history and heritage of the pattern lest folks get the idea that ASP.NET MVC is something clever or new.

whibr
whibr
28 Jan 2010

Great post! One question, when, or rather, why, would one decide to use MVP over say MVVM, or vise versa?

28 Jan 2010

Hi whibr,

From a flexibility point of view, the Presenter has access to the View, so Model View Presenter can generally handle any scenario you can think of. Model View ViewModel has to rely on using properties and events for communicating state changes, so for some types of interactions it can become a little convoluted to use MVVM.

A good example is closing the view. Does the ViewModel raise an IsClosing event? That makes a lot of assumptions about how the View works. Perhaps the ViewModel raises a Done event that the view can interpret. There are lots of ways to tackle them, but in MVP you'd simply call View.Close(). So I feel that MVP is a better choice if you want to standardize on a pattern that will always work.

From a testing point of view MVVM lends itself to state based testing, whereas MVP generally involves interaction based testing. That is, with MVVM, a test might set a property, then assert that the property was set. With MVP, you might need to mock the view to check if a method was called.

So I think it comes down to simplicity - MVVM is generally less code and supports most scenarios, MVP has a little more power but a little more cost. Ideally you wouldn't standardize on one pattern or the other, but use either when they make the most sense. The MVP pattern I blogged about also shows how MVP and MVVM could be combined.

Paul

whibr
whibr
28 Jan 2010

wow, what a fantastic resource! thanks for your reply & time Paul - much appreciated!

27 Mar 2010

Paul, The statement that MVC is impossible in WPF is untrue. It's only useful in very specialized contexts (when creating custom controls). For instance the Button.Click event orignates from the Button control itself. In this context the code-behind for the button control is considered the Controller and the XAML is the view.

In fact when you think about it. The code-behind for any lookless control (and user control) would be considered the C in classic MVC.

The C in ASP.NET MVC and Ruby on Rails and other current Triad solutions is indeed not the classic Smalltalk C. This is what Martin Fowler calls Front Controller. In ASP.NET MVC the "Controllers" are actually command objects. This is very similar to how Jakarta Struts operated (at least back when I used it).