TSM - MVVM in Windows Phone 8

Cosmin Stirbu - iOS Software Developer

One of the major differences between Model-View-Controller and MVVM is that the ViewModel objects do not have a reference to the View objects. The View object binds to the properties of the ViewModel object which in return exposes the data from the Model and other View specific properties. The binding mechanism assures that when the properties from the ViewModel change, the ones from the View are automatically updated and vice-versa. When the user presses a button, a command is invoked in the ViewModel, the View doesn"t ever modify the entities from the Model directly. The View classes are not aware of the Model classes while the ViewModel and the Model classes are not aware of the View classes. In this way, the View objects are merely a consumer of the ViewModel objects, and they can be easily replaced with unit tests.

How do we apply MVVM in Windows Phone 8?

MVVM Light is a great and very popular toolkit, developed and maintained by Laurent Bugnion used for fast development of MVVM applications in WPF, Silverlight and Windows Phone. This toolkit helps us to separate the View from the Model so we can write cleaner, easy to maintain and extend applications, the user interface layer (the code behind) is as thin as possible and so the applications are easy to develop and to automatically test.

Source: blogs.msdn.com/b/tims/archive/2010/11/02/kung-fu-silverlight-architectural-patterns-and-practices-with-mvvm-and-ria-services.aspx

One of the components offered by the toolkit is ViewModelBase class, a class that each ViewModel class can extend and so it doesn"t have to implement INotifyPropertyChanged to notify the View when a property changes. Usually in a Windows Phone 8 application, for each Page there is a corresponding ViewModel object that extends the VIewModelBase class. Another big advantage of using the class ViewModelBase is its IsInDesginMode property that allows us to check if we are using Expression Blend or Visual Studio Designer and if so, to offer "design data" so the designer would have a much easier job. We have to do this because neither Blend nor Visual Studio Designer allows networking operations or database connections.

The general approach is to expose all our ViewModel objects as properties using the class ViewModelLocator (offered by MVVM Light). In this class we can use a preferred IoC Container (or SimpleIoc included in MVVM light) to create the ViewModel objects and inject dependencies into them (for instance an interface that exposes methods to manage entities from the model).

A ViewModelLocator object can be added as a resource in App.xaml and then used by each page to bind its DataContext property to the corresponding ViewModel property exposed by the ViewModelLocator object.

ViewModelLocator object added automatically as a resource in App.xaml when creating a new project using the MVVM Light Visual Studio template.


  
    
    
    
      ...
   
  

We can bind the DataContext of our Page to the ViewModel object exposed by the ViewModelLocator using Blend (but also directly in the .xaml file). After that we can bind all the properties that we need from our ViewModel to UI elements (and not only) from the Page.

If we want for instance to display some text in a TextBlock object all we have to do is to bind its Text property to a string property from the ViewModel object, in this way we don"t have to write any code behind. The binding can be done in Blend and as well in the XAML code.

string _textProperty
public string TextProperty
{
  get
  {
     return _textProperty;
  }
  set
  {
  if (_textProperty != value)
  {
    _textProperty = value;
    RaisePropertyChanged("TextProperty");
   }
  }
}

The call of the inherited method RaisePropertyChanged assures that the UI will update every time the value of the property changes.

The binding code looks like this:

Basically any property of any UI element can be bound to any property from the ViewModel object without having to write any code behind. We can for instance bind the ItemSource property of a ListBox to a List property in a ViewModel and then configure the ItemTemplate for the ListBox that will have as DataContext a T object which conceptually speaking is also a ViewModel (or an ItemViewModel).

How does the View communicate with the ViewModel?

MVVM Light offers EventToCommand class that extends Behavior class and allows the binding of an event to a command property in the ViewModel. In this way when a new event is raised we can execute the code in the ViewModel without having to write any code behind code. In the ViewModel we can expose a RelayCommand property which using EventToCommand we can bind it to any event.

The Click event of a button is bound to ButtonPressed command

 

// Button Pressed
public RelayCommand ButtonPressed
{
  get
  {
    return new RelayCommand(() =>
    {
    Console.WriteLine("Button Pressed");
    });
  }
} 

We should mention that when using EventToCommand we can also send parameters, for instance we can send the text from a TextBox by binding the event to a RelayCommand command. EventToCommand can be attached to any UI element, even to the Page itself, in this way we can invoke a command when the page has loaded (Loaded event) to fetch some data from a web service for instance.

How does the ViewModel communicate with the View?

Besides the binding mechanism the ViewModel can communicate with the View through other mechanisms such as Behavior, Messenger or by using interfaces implemented by the View and injected in the ViewModel.

By extending the Behavior class we can expose properties (DependencyProperty) together with regular properties that we can bind to properties from the ViewModel, in this way, when the ViewModel properties change we can execute UI code. The advantages of Behavior objects are that they can be easily reused, they are "blendable" and they allow us to move the code behind away from the View.

MVVM Light offers a Messenger class used by different objects to communicate in the application through a low coupling mechanism. The messages can contain simple data types or more complex ones. This class is often used to allow the ViewModel objects to communicate or to allow the ViewModel objects to communicate with the View.

Another approach is to create interfaces that will be implemented by the View. For instance if we want to display an alert in the View we can create an interface that exposes those methods, implement it in the View and after that inject it in the ViewModel (we can get a reference of the ViewModel by using the DataContext property).

We should mention that the preferred way to handle this communication is Behaviors, although MVVM doesn"t clearly specify this, it is quite clear that as long as the code behind is kept to a minimum the application is easier to test. A disadvantage of Behaviors is that they are not available in Windows 8 out of the box, so the code would be less portable, but there are libraries that offer classes similar to Behavior classes. (WinRtBehaviors - http://winrtbehaviors.codeplex.com/)

Common challenges and their solutions

One of the common problems is navigation: from where do we navigate to another Page and how? The solution is quite simple - we create an interface that exposes the needed methods for navigation, implement it in a dedicated class and inject it in the ViewModel objects from where we want to perform the navigation.

Another problem is offering design time data - the recommended approach is the creation of interfaces for the data managers (classes where we have access logic, persistence logic) and implementing them in two different classes (one for design time, and one for production). Using the IsInDesignMode property we can register in the IoC container the corresponding class that later will be injected in the ViewModel. This feature combined with Blend gives the possibility of having both developer and design teams to work at the same time on the project.

Behavior classes allow us to make the transition between different states of a Page and even to trigger animations, this being possible without writing any code behind. Behavior classes such as DataStateBehavior and GoToStateAction allow this.

In Windows Phone 8 unfortunately we cannot bind the Application Bar to different commands in the ViewModel out of the box (this is possible in Windows 8). So this can be one of the situations where we have to write code behind, to listen to events from the Application Bar buttons and invoke the commands from the ViewModel manually. But if we don"t want to do this (and usually we don"t) we can use the AppBarUtils library (http://appbarutils.codeplex.com/) that offers Behavior, Trigger and Action classes that allow the binding to different commands and other properties.

Conclusions

The MVVM design pattern is very popular among Windows Phone developers, it allows fast application development that are easy to maintain, extend and test and it also allows a fast user interface development (Blend). The components defined by the pattern have clearly defined responsibilities and the coupling is kept to a minimum. If when the design pattern was introduced its implementation seemed pretty difficult because it required a lot of code lines, nowadays the libraries and the toolkits found in the community makes it much more fun and interesting.

References

MVVM Light www.galasoft.ch/mvvm/

msdn.microsoft.com/en-us/magazine/jj651572.aspx

appbarutils.codeplex.com/

winrtbehaviors.codeplex.com/

vimeo.com/53068482

channel9.msdn.com/Events/TechDays/Techdays-2012-the-Netherlands/2264

outcoldman.com/en/blog/show/308

blogs.msdn.com/b/tims/archive/2010/11/02/kung-fu-silverlight-architectural-patterns-and-practices-with-mvvm-and-ria-services.aspx