Udostępnij za pośrednictwem


Presentation Model Pattern in WPF

Choosing a design pattern for the user interface of your application involves weighing trade-offs between testability, complexity, developer tool support, and capabilities. There are two very prominent camps in user interface patterns: Forms & Controls and Model-View-Something (Controller, Presenter, ViewModel, etc.). Martin Fowlers’ article GUI Architectures (https://www.martinfowler.com/eaaDev/uiArchs.html ) provides a detailed history and comparison of some of these approaches.

Many applications use Forms & Controls pattern for their user interface. This is partially because it is the default pattern Visual Studio uses to create an application and more likely because it is a very simple pattern with a low barrier of entry for developers. Though Forms & Controls approach may be simpler to implement for small applications which can get away with limited or no unit testing, larger and more complex applications are increasingly difficult to maintain using this approach. This inherent lack of testability of a Forms & Controls pattern make is a poor choice for implementing larger applications.

To solve this problem of testability, software architects have turned to more advanced user interface patterns such as Model-View-Controller, Model-View-Presenter (a.k.a. Supervising Controller and Passive View), Presentation Model, and other variants of these patterns. The goal of these patterns is creating user interface classes which can be easily tested, and minimizing the amount of code which resides in the view (a notoriously difficult part of the application to test in an automated fashion). Though these patterns are technology independent, the underlying GUI framework lends itself to certain patterns. Windows Forms technology meshed particularly well with the Model-View-Presenter pattern, while implementing a Presentation Model pattern in Windows Forms required masses of synchronization code. Windows Presentation Foundation, on the other hand, fits very well with the Presentation Model because of its advanced data binding technology which eliminates the need to write masses of synchronization code between the view and presentation model.

Each screen is implemented as a View and Presentation Model pair. Each class has distinct responsibilities. The view is responsible for how data is presented on the screen, and the presentation model is responsible for what gets presented on the screen and the actions which can be performed on that data.

The view consists of both the XAML and the code-behind, and displays the data it gets from the presentation model. Most views will be implemented mostly in XAML with a little supporting C#. Layout and user interaction are the primary responsibilities of the view. The view interprets user actions and forwards them to the presentation model as commands.

Commands are used to invoke behavior. The command pattern decouples the presentation model from the actual input event which invoked some functionality. Commands capture the intent of the user, not necessarily the actual mechanics of how they indicated that intent. For example, the presentation model doesn’t need to know if the user clicked the save button, pressed CTRL+S, or selected save from a menu option. All the presentation model needs to concern itself with is that the data should be saved. The command object also provides a good mechanism for the presentation model to indicate if an action is enabled through the CanExecute callback of the command.

While the PresentationModel receives communication from the View via Commands, if it needs to notify the View of something, it should use events. Events allow us to define the means of communication on the presentation model itself. While some events should be built into the presentation model base class (notifying when properties changed), others are screen specific and should be in the screen’s presentation model. There is no separate interface implemented by the View as in MVP. Having the presentation model provide events simplifies unit test code, because you don’t need to create dummy views.

We’ll cover more in part 2.

Comments

  • Anonymous
    June 20, 2008
    PingBack from http://blog.a-foton.ru/2008/06/21/presentation-model-pattern-in-wpf/

  • Anonymous
    July 09, 2008
    Great article, Matt. I'm slowly starting to see that PM / V-VM-M really is the better way with WPF. The only one thing I'm still not quite conviced about is state changes. Imagine an animated transition between screens. With MVP, the Presenter would tell the view to start the transition, the view would change (e.g. play storyboards etc) and fire an event to the presenter on completion. How would you do that with a View/ViewModel combination?

  • Anonymous
    July 09, 2008
    An animated transition between pages is really no different than any transition between pages.  When the target page loads, it's going to load it's presentation model (which may or may not receive some state from the previous page).  The presentation model really doesn't care when the animation is done, and really you probably want your data loaded before the animation is done if possible so that the transition looks seamless.  The view has the option of not showing/creating the controls which are bound to the data until it's animation is done.   My current app shows a "Loading..." animation when most pages load (because I'm calling a bunch of web services which take some time).  The view waits for all the web services (asynchronously called) to complete (notified via an "Initialized" event on the target PM) before fading out the "Loading" animation and showing the controls which are bound to the PM.

  • Anonymous
    July 12, 2008
    Do you have some sample app for public share matt?