Separating user interface code from everything else is a key principle in well-engineered software. But it’s not always easy to follow and it leads to more abstraction in an application that is hard to understand. Quite a lot design patterns try to target this scenario: MVC, MVP, Supervising Controller, Passive View, PresentationModel, Model-View-ViewModel, etc. The reason for this variety of patterns is that this problem domain is too big to be solved by one generic solution. However, each UI Framework has its own unique characteristics and so they work better with some patterns than with others.
The WPF Application Framework (WAF) provides support for the Model-View-ViewModel Pattern because this one works best with Windows Presentation Foundation (WPF) applications. This pattern is also known as PresentationModel pattern.
MSDN: A variant of the Presentation Model pattern named Model-View-ViewModel is commonly used in Windows Presentation Foundation applications.
Represent the state and behavior of the presentation independently of the GUI controls used in the interface.
The most approved description of this design pattern is done by Martin Fowler. You can read his article online on his website. The following chapters describe our specific .NET implementation of this design pattern.
The following UML class diagram shows the collaborating classes of this design pattern in a logical layered architecture.
Figure 1: The structure of the Model-View-ViewModel Pattern
The types participating in this pattern are:
- View contains the specific GUI controls and defines the appearance of the user interface.
- IView declares the interface of the View. The ViewModel can communicate over this interface with the View. Related pattern: Separated Interface (PoEA).
- ViewModel represents the state and behavior of the presentation.
- Model can be a business object from the domain layer or a service which provides the necessary data.
- Controller is responsible for the workflow of the application. Furthermore, it mediates between the ViewModels. So it promotes loose coupling by keeping the ViewModels from referring to each other explicitly. Related patterns: Application Controller (PoEA), Mediator (GoF)
- The View can call operations on the ViewModel directly. The ViewModel needs to communicate through the IView interface when it has to update the view.
- The View can collaborate with the Model but it should restrict this on simple data binding. It’s recommended to handle more complex operations by the ViewModel.
- The upward communication from the Model to the View or to the ViewModel is done through events. Especially, the property changed events can be raised on the Model to trigger the WPF data binding implementation. Related pattern: Observer (GoF).
- The Controller can call operations on the ViewModel directly, whereas the backward communication from the ViewModel to the Controller might be done through events. Related pattern: Observer (GoF).
This specific implementation of the ViewModel pattern has the following liabilities:
- The ViewModel is dependent on a specific GUI framework. We use the commanding and the weak event concept of WPF.
- When the ViewModel wants to listen to events of the model then you have to implement weak event listeners. Otherwise, you might produce a memory leak in your application. Note: The WPF data binding implementation uses the same concept internally.
The WPF Application Framework (WAF) provides some types which helps you to implement this pattern.
Derive your ViewModel implementation from this class. The ViewModel class provides a default implementation of a weak event listener and it is responsible that the DataContext of the WPF view gets the instance of your ViewModel.
If your ViewModel implementation gets too big or you have low cohesion in your class then you can divide the ViewModel into a root ViewModel class and one or more child ViewModel classes. In this case your child ViewModels must pass the value ‘true’ for the child constructor parameter of the base class. Additionally, the root ViewModel has to expose its child ViewModel objects to the View (e.g. through a property) because the View has only an association to the root ViewModel.
All WPF views that are managed by a ViewModel have to implement this interface. You can create your own interface for exposing properties and methods of the View. We recommend to inherit own View interfaces from the IView interface.
This class provides a simple implementation for the ICommand interface. The constructor requires a delegate which is called when the command is executed. A second delegate can be passed to the constructor which is called when the command needs to refresh its state. With the second delegate it’s possible to define when the command should be disabled. The command state refresh is triggered through the RaiseCanExecuteChanged method.
This command implementation is an ideal candidate for the ViewModel. By using the DelegateCommand, the ViewModel gets informed when it should handle a user interface action (e.g. Button was clicked). You need to expose the commands in the ViewModel through properties and bind in the View on them.
- WPF Application Framework (WAF) http://waf.codeplex.com/Wiki/View.aspx?title=Model-View-ViewModel%20Pattern
|Share this post :|