Theory The theory beyond the pattern

MVVM stands for Model - View - ViewModel and it is a pattern used when dealing with views created (mainly) with WPF technology (even when it can be used with other technologies as well it is not so common).

As anyone can work out by its name it is composed by three elements:

View
Responsibility

To present the data available at the DataContext to the end user to allow him to interact with it.

Design Tips

Avoid putting logic on the View even when XAML allows to do it. Prefer moving that logic to the ViewModel over adding it to the View because:

  • XAML logic cannot be debugged.
  • XAML logic cannot be tested.
Model
Responsibility

To model a business object containing the required data.

Design Tips

As the model is only a representation of the data of a business entity (object) it should contain only properties containing object’s data and constructors.

Implementing INotifyPropertyChanged is right as we consider this part of the object’s responsibility.

ViewModel
Responsibility

To contain the logic that acts as a bridge between the View and the Model.

Design Tips

Avoid putting too much logic inside the ViewModel and consider creating more classes (services, engines, etc.) if the ViewModel logic is too big to fit in one class.

Include always a reference to the model on the ViewModel.


The MVVM pattern provides the following benefits:

  • It helps to have a better Separation of concerns.
  • It allows to replace the View with a new one without changing the ViewModel.
  • It allows to easily unit test View's logic as now it is in a normal class (the ViewModel).
  • It allows graphics designers to work in the View without touching any logic.

The next diagram shows the basic layers every MVVM implementation should have. It shows the allowed dependencies and the forbidden ones too:

Layers and dependecies of the MVVM pattern

The following is the list of allowed and forbidden dependencies:

  1. The View's code behind should not reference the ViewModel. It is only allowed when calling DataContext's commands from View's events (but there are better ways of doing it without adding this dependency).
  2. The View cannot reference anything from the Model. Neither code behind nor Bindings can talk with Model objects, only ViewModel ones.
  3. The ViewModel should contain always a Model reference.
  4. It is completely forbiden that the Model knows anything from the ViewModel. That indicates a flawed design for sure.
  5. The ViewModel must not know anything from the View as one ViewModel can work with different Views.