The Model-View-ViewModel (MVVM) pattern provides a flexible way to build Silverlight applications that promotes code re-use, simplifies maintenance and supports testing. The pattern consists of three different components including the Model (entities and code on the server), the View (the Silverlight screens) and the ViewModel (the glue between the Model and the View).

The essential aspects of MVVM are: The Model, the View and the ViewModel.

MVVM is defined by the separation of the Model from the View from the ViewModel. This separation pattern clearly delineates the responsibilities of each of the essential aspects of MVVM.

Model

The Model contains the data points that the application requires. Sometimes this comes from a WCF service, a RESTful service, or data aggregated from many places. Where the data comes from is irrelevant. What’s important is that the data is pulled into the client and stored in the Model.

Lets take an example of twitter client,the model may contain classes for User, Tweet, and Tweets. These classes (sometimes known as domain objects) may be collection classes or single entity classes. The main responsibility of a Model is to describe the data required by the client.

public class Tweet : INotifyPropertyChanged
{
    protected const string UserNameProperty = "UserName";
    private string _userName;

    public string UserName
    {
        get { return _userName; }
        set
        {
            if (_userName == value) return; _userName = value;
            NotifyPropertyChanged(UserNameProperty);
        }
    }

    #region INotifyPropertyChanged Members

    /// <summary>Event to notify upadte in view model properties</summary>
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>Raises the <see cref="PropertyChanged"/> event</summary>
    /// <param name="propName"></param>
    public void NotifyPropertyChanged(string propName)
    {
        if (PropertyChanged != null)
            PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propName));
    }    #endregion
}

The Tweet class conatins a host of properties such as UserName. All of the properties call the NotifyPropertyChanged method. The INotifyPropertyChanged is a simple interface that implements a PropertyChanged, which is what a Model needs to communicate to a View’s controls that something about a property has changed.

View

The View is the friendly presentation of information to the user. A View may include themes, styles, controls, bindings, events, and other interactions on the screen. The View’s responsibility is to keep all presentation in a single place, unencumbered by logic and other heavier code. Often the View will have controls that will map to one or more Model’s data points. (In Silverlight, Windows Phone and WPF these controls often map declaratively through data binding XAML markup.)

The TimelineView of our Twitter app has a ListBox that defines an ItemTemplate for displaying the individual tweets. Timeline-View is databound to the TimelineViewModel declaratively in the XAML. First, the ViewModel is created as a static resource:

<phone:PhoneApplicationPage.Resources>
  <local:TimelineViewModel x:Key="TimelineViewModel" />
</phone:PhoneApplicationPage.Resources>

Then the View is data bound to the ViewModel by setting the DataContext. In the sample app I do this in the outermost panel in the page, which happens to be the Grid:

DataContext="{Binding Source={StaticResource TimelineViewModel}}"

View Model

The ViewModel is the glue between the View and the Model(s). The ViewModel is also known as the “View’s Model” because it exposes public properties intended for the View. Often the ViewModel aggregates one or more Models and exposes them to the View as public properties.

The ViewModel is intended for the View, so aggregating the Models in the ViewModel allows the same Models to be reused by many ViewModels (and thus by many Views). Abstraction and aggregation of Models is just one aspect of a ViewModel, however.

Sometimes a View may require a data point not in any Model. This might be a UI-specific property like IsBusy for a ProgressBar control, or some calculated property using logic. These View-specific data points can be created in the ViewModel as public properties without muddying the Models. This is abstraction and separation at its core.

But that’s not all a ViewModel does. As I mentioned, a ViewModel is the glue between the View and the Model. Because XAML has a great binding story, MVVM really shines. The View’s DataContext is set to an instance of a ViewModel class. This gives the View access to all the public properties in the ViewModel.

There are other variants and extensions of what the members of the MVVM triad can do. For example, does the ViewModel go get the data and load the Model(s), or do the Model(s) know how to load themselves? (I highly recommend and prefer the former.)

Whatever your choice, it’s still MVVM. You can also debate methods to bind the View to the ViewModel. Whether you do it in XAML, the codebehind, the ViewModel or in a third-party class (what I call the marriage between View and ViewModel), its still MVVM. My point here is that you and your developer colleagues may deviate and differ on how to implement MVVM, but at its core MVVM is just the separation of the MVVM members

The TimelineViewModel class has a Tweets property, which is an ObservableCollection<Tweet> that aggregates a collection of instances of the Model class for the View in my sample app.

This example just uses a single Model, but in many cases the ViewModel may aggregate multiple Model classes, which could even be object graphs. The ViewModel is built to handle customizing the exposure of the data for the View. What I mean by this is that the ViewModel can aggregate one or more Model classes and add other properties that the View may need. For example, my View may need to bind to properties such as IsBusy or LoggedInAsName, neither of which are in the Model Tweet. I can simply add these to the ViewModel as needed

The ViewModel also handles presentation logic. One simple example of this is the job of making the call to go get the latest tweets and loading the Tweets property in the ViewModel.

I like my ViewModel classes to direct the data manipulation calls; however, I abstract the calls to a data service, then out to its own class. In this example I would create a class called TwitterService and it would then make the API calls to Twitter. The ViewModel would just call the TwitterService class’s GetTweets method. I find this abstraction really nice for three big reasons. First, it hides the Web service API calls from the ViewModel, which really could care less about how it gets its data.

For a detailed walkthrough on MVVM, visit Using the MVVM Pattern in Silverlight Applications.

Related Links


This article referes to John Papa’s Papa’s Perspective for references.

Share your thoughts

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s