Getting Started with the MVVM Pattern in Silverlight Applications

With the increasing popularity of Silverlight as an application development framework the discussion of patterns has grown louder and louder. Fortunately the majority of developers building Silverlight applications have agreed on a pattern that fits well in the Silverlight world called Model-View-ViewModel (MVVM). The MVVM pattern allows applications to be divided up into separate layers that provide multiple benefits ranging from better code re-use to enhanced testing capabilities. This post will explain key concepts found in the MVVM pattern and attempt to present them in a way that is easy to understand. I’ll show some code along the way to demonstrate how the MVVM pattern can be used and provide a few alternatives when it comes to binding data. The code shown later in the post can be downloaded here.

Getting Started with the MVVM Pattern

The MVVM pattern defines three key parts including the Model, the View and the ViewModel. The following image shows a slide from a Silverlight course we offer that sums up the role of each part of the MVVM pattern in a concise way:

clip_image002


Looking through the description of each part you can see that the Model represents the business domain which includes the model classes used (Customer, Order, etc.), data access code and business rules. In general you can think of the Model as representing the entities that live on the server as well as the objects that are responsible for interacting with the data store your application uses and filling entities with data. While some people feel that the Model represents only the model classes (classes like Customer, Order, etc.) used in the application I personally think of it more broadly and include data access code and business rules in the Model definition. Silverlight applications will call into the Model code through services written using WCF, ASMX, REST or even custom solutions.

The View in MVVM represents the Silverlight screens that you build. This includes the XAML files and the code-beside files that are responsible for showing data to end users. The View's responsibilities include displaying data and collecting data from end users. A given View isn't responsible for retrieving data, performing any business rules or validating data.

The ViewModel acts as the middle-man between the View and the Model. It's responsible for aggregating and storing data that will be bound to a View. For example, a ViewModel may contain a List<State> property and a List<Person> property that may be bound to two ComboBox controls in a View. The ViewModel will retrieve the values held by these two properties from the Model. By using a ViewModel the View doesn't have to worry about retrieving data and knows nothing about where data comes from.

Additional players may be added into the Model-View-ViewModel mix to help segregate code even further. For example, I normally create a service agent class that is responsible for making calls from Silverlight to remote services. The service agent is responsible for initiating the service call, capturing the data that's returned and forwarding the data back to the ViewModel. By doing this the ViewModel classes can delegate data gathering responsibilities to the service agent. A given service agent can also be re-used across multiple ViewModel classes as needed. The following image shows how the service agent can be integrated into the MVVM pattern:

clip_image004

 

When developers first start building Silverlight applications they typically add all of the code for the application into the XAML's code-beside file (MainPage.xaml.cs for example). Although this approach certainly works, by following the MVVM pattern you can take advantage of several inherent benefits including better code re-use, simplified maintenance, more modular code and enhanced testing support. I'll focus on the overall benefits achieved by building applications that are based on the MVVM pattern throughout the rest of this article.

The Model

There are many different ways that the Model can be created including using Microsoft's Entity Framework or LINQ to SQL technologies, nHibernate, PLINQO, SubSonic, custom solutions and more. The technology chosen is generally unique to a given company's development policies so I'm not going to go into a discussion of the pros and cons of each technology here. What's important is that one or more classes used by a Silverlight application are "modeled" using tools or by writing code by hand. This involves defining all of the properties that each class will expose. A simple example of a Model class is shown next:

public class Person
{
    public string FirstName { get;set;}
    public string LastName { get;set; }
    public int Age { get; set; }
}

 

Once the Model classes are in place they'll need to be populated with data from a data store which can be done by writing custom code or using ORM frameworks that handle mapping query results to object instances. Services will also need to be written to expose one or more of the Model classes used in a Silverlight application which can be done using WCF, ASMX or even custom REST services.

The View and ViewModel Classes

Once the Model is ready to go the View and ViewModel classes can be created. As mentioned earlier, a View represents a Silverlight screen that end users interact with which includes the XAML file and the associated code-beside file. Rather than adding all of the code to call the Model and retrieve data directly into the View's code-beside file, the View will rely on a ViewModel class to retrieve data and then bind to the properties of the ViewModel.

ViewModel classes should implement an interface that's available in Silverlight called INotifyPropertyChanged which defines a single event named PropertyChanged. This event is used to notify different Silverlight bindings that data has changed for one or more properties so that controls can be updated automatically. Although INotifyPropertyChanged can be implemented directly on a ViewModel class, your application may have multiple ViewModel classes in it and writing the same code over and over tends to get old. Creating a base ViewModel class that handles implementing INotifyPropertyChanged is useful to minimize code and allow more re-use to occur in applications. The following code shows a class named ViewModelBase that implements the INotifyPropertyChanged interface. The class also provides an OnNotifyPropertyChanged method that can be used to raise the PropertyChanged event.

public class ViewModelBase : INotifyPropertyChanged
{
    protected void OnNotifyPropertyChanged(string p)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(p));
        }
    }

    public bool IsDesignTime
    {
        get
        {
            return (Application.Current == null) || (Application.Current.GetType() == typeof(Application));
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
}

 

A ViewModel class can derive from ViewModelBase and automatically take advantage of the INotifyPropertyChanged interface. An example of a ViewModel class named PeopleViewModel that derives from the ViewModelBase class and defines several properties and methods is shown next:

public class PeopleViewModel : ViewModelBase
{
    IServiceAgent _ServiceAgent;
    Person _Person;
    ObservableCollection<Person> _People;

    public PeopleViewModel() : this(new ServiceAgent()) {}

    public PeopleViewModel(IServiceAgent serviceAgent)
    {
        if (!IsDesignTime)
        {
            _ServiceAgent = serviceAgent;
            GetPeople();
        }
    }

    #region Properties

    public Person Person
    {
        get
        {
            return _Person;
        }
        set
        {
            if (_Person != value)
            {
                _Person = value;
                OnNotifyPropertyChanged("Person");
            }
        }
    }

    public ObservableCollection<Person> People {
        get
        {
            return _People;
        }
        set
        {
            if (_People != value)
            {
                _People = value;
                OnNotifyPropertyChanged("People");
            }
        }

    }

    #endregion        
    
    public void GetPeople()
    {
        _ServiceAgent.GetPeople((s,e) => this.People = e.Result);
    }

    public void UpdatePerson()
    {
        _ServiceAgent.UpdatePerson(this.Person, (s, e) =>
        {
            PeopleEventBus.OnOperationCompleted(this, new OperationCompletedEventArgs { OperationStatus = e.Result });
        });
    }
}


Looking through the code you'll see that PeopleViewModel defines two fields, two properties and two methods. Each property raises the PropertyChanged event as the set block is called by calling the OnNotifyPropertyChanged method defined in ViewModelBase. This notifies any controls bound to the properties that the values have changed which allows them to update the data they display automatically. 

Looking at the first constructor in PeopleViewModel you'll see that it forwards the call to a secondary constructor that accepts a parameter of type IServiceAgent. Why have two constructors? This approach allows testing frameworks to pass in different types of service agents to the ViewModel when running tests. When the ViewModel is called at runtime the parameterless constructor will be called and an instance of a ServiceAgent class (shown next) will be passed as the IServiceAgent parameter. From there, once the service agent object is passed into the ViewModel's constructor a call to a method named GetPeople is made which invokes a method on the service agent and passes a callback delegate. The WCF service is then called by the service agent and the results are assigned to the People property.

 

public interface IServiceAgent
{
    void GetPeople(EventHandler<GetPeopleCompletedEventArgs> callback);
    void UpdatePerson(Person p, EventHandler<UpdatePersonCompletedEventArgs> callback);
}

public class ServiceAgent : IServiceAgent
{
    public void GetPeople(EventHandler<GetPeopleCompletedEventArgs> callback)
    {
        PeopleServiceClient proxy = new PeopleServiceClient();
        proxy.GetPeopleCompleted += callback;
        proxy.GetPeopleAsync();
    }

    public void UpdatePerson(Person p, EventHandler<UpdatePersonCompletedEventArgs> callback)
    {
        PeopleServiceClient proxy = new PeopleServiceClient();
        proxy.UpdatePersonCompleted += callback;
        proxy.UpdatePersonAsync(p);
    }
}

 

Binding a ViewModel to a View

Now that the ViewModel class is defined it can be bound to a View. This can be done declaratively in XAML or imperatively through code in the View's code-beside file. Imperative (or code-based) binding is typically accomplished by assigning a ViewModel instance to the layout root's DataContext property as shown next:

this.LayoutRoot.DataContext = new PeopleViewModel();

An example of declaratively binding a ViewModel (which is my personal preference) to a View is shown next:

<UserControl x:Class="ViewModelExample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:converter="clr-namespace:ViewModelExample"
    xmlns:viewModel="clr-namespace:ViewModelExample.ViewModel"
    mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480">
    <UserControl.Resources>
        <viewModel:PeopleViewModel x:Key="ViewModel" />
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource ViewModel}}">
    </Grid>
</UserControl>

 

The ViewModel namespace is first referenced using an XML namespace prefix of "viewModel". The ViewModel is then defined in the UserControl's Resources section and given a key of "ViewModel" (note that any name can be chosen for the key). The key is important since it's used to hook the ViewModel to the DataContext of the layout root using the {Binding Source={StaticResource ViewModel}} syntax. The declarative binding will cause a new PeopleViewModel instance to be created at runtime which is then bound to the layout root's DataContext. Child controls of the layout root can then bind to properties on the ViewModel. An example of binding a ListBox to the ViewModel's People property and a StackPanel to the Person property is shown next:

<StackPanel Margin="20">
    <TextBlock Text="Binding Controls to a ViewModel" Margin="20,0,0,0" FontWeight="Bold" FontSize="12" />
        <ListBox x:Name="lbPeople" Margin="0,10,0,0" Height="250" Width="300" HorizontalAlignment="Left"
                 ItemsSource="{Binding People}" ScrollViewer.HorizontalScrollBarVisibility="Hidden"
                 SelectedItem="{Binding Person, Mode=TwoWay}">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="100" />
                            <ColumnDefinition Width="100" />
                            <ColumnDefinition Width="100" />
                        </Grid.ColumnDefinitions>
                        <TextBlock Grid.Column="0" Margin="10" Text="{Binding FirstName}" />
                        <TextBlock Grid.Column="1" Margin="10" Text="{Binding LastName}" />
                        <TextBlock Grid.Column="2" Margin="10" Text="{Binding Age}" />
                    </Grid>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <StackPanel DataContext="{Binding Person}">
            <TextBlock Text="First Name" Margin="0,10,0,0" />
            <TextBox Text="{Binding FirstName,Mode=TwoWay}" Width="100" Height="25" HorizontalAlignment="Left"/>
            <TextBlock Text="Last Name" />
            <TextBox Text="{Binding LastName,Mode=TwoWay}" Width="100" Height="25" HorizontalAlignment="Left"/>
            <TextBlock Text="Age" />
            <TextBox Text="{Binding Age,Mode=TwoWay}" Width="100" Height="25" HorizontalAlignment="Left"/>
        </StackPanel>
        <Button Margin="0,10,0,0" Click="Button_Click" Content="Submit" Height="20" Width="100" HorizontalAlignment="Left" />
</StackPanel>

 

The MVVM pattern provides a flexible way to work with data that encourages code re-use and simplifies maintenance. There's much more that can be discussed with regard to the MVVM pattern in Silverlight such as event buses, commanding and dependency injection but I hope this post helps jumpstart the process of architecting and developing Silverlight applications. If you have specific Silverlight development concepts you'd like to see covered in future posts tweet me at @DanWahlin or add a comment below.

Published Tuesday, December 08, 2009 11:30 PM by dwahlin

Comments

# Twitter Trackbacks for Getting Started with the MVVM Pattern in Silverlight Applications - Dan Wahlin's WebLog [asp.net] on Topsy.com

Pingback from  Twitter Trackbacks for                 Getting Started with the MVVM Pattern in Silverlight Applications - Dan Wahlin's WebLog         [asp.net]        on Topsy.com

# Dew Drop &#8211; December 9, 2009 | Alvin Ashcraft&#039;s Morning Dew

Wednesday, December 09, 2009 9:04 AM by Dew Drop – December 9, 2009 | Alvin Ashcraft's Morning Dew

Pingback from  Dew Drop &#8211; December 9, 2009 | Alvin Ashcraft&#039;s Morning Dew

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Wednesday, December 09, 2009 9:55 AM by lesnikowski

How about using PostSharp for INotifyPropertyChanged implementation:

www.lesnikowski.com/.../inotifypropertychanged-with-postsharp

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Wednesday, December 09, 2009 11:21 AM by Michael Palermo

Dan, this is the best MVVM intro I have seen so far!  You rock!

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Wednesday, December 09, 2009 11:41 AM by alexy

Thanks Dan for this important post.

Look forward to hear more from you about MVVM.

Would be nice to have the same simple MVVM overview with WCF RIA included

# Articles on MVVW &laquo; QuantuMatrix&#8217;s Weblog

Wednesday, December 09, 2009 4:52 PM by Articles on MVVW « QuantuMatrix’s Weblog

Pingback from  Articles on MVVW &laquo; QuantuMatrix&#8217;s Weblog

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Thursday, December 10, 2009 10:02 AM by dwahlin

Mike:

Thanks....glad you found it useful.

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Thursday, December 10, 2009 10:03 AM by dwahlin

alexy:

Thanks.  I'll see what I can do to integrate RIA Services into the mix for another post.

# Links (12/10/2009) &laquo; Steve Pietrek-Everything SharePoint/Silverlight

Pingback from  Links (12/10/2009) &laquo; Steve Pietrek-Everything SharePoint/Silverlight

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Friday, December 11, 2009 2:38 AM by BerndH

Dan, I am glad to hear that I am not the only person to include business behaviour into the model. The business layer is exactly the part that is missing in most of the MVVM descriptions/explanations.

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Friday, December 11, 2009 2:56 AM by dwahlin

BerndH:

I'm glad to hear I'm not the only one who thinks that way. :-)  Thanks for taking the time to leave a comment.

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Friday, December 11, 2009 2:19 PM by Matt

Great intro, but I've got a question about the ServiceAgent.  In a larger project, would you have a PeopleServiceAgent and ProductServiceAgent?  Or am I not looking at this the correct way?

Thanks!

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Saturday, December 12, 2009 11:06 AM by dwahlin

Matt:

That's how I'd do it. I actually use a simplified Service Agent though that can handle any methods to keep code to a minimum in the Silverlight assembly.  The following post covers the details:

weblogs.asp.net/.../simplifying-the-process-of-calling-a-wcf-service-from-silverlight-or-any-net-application.aspx

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Monday, December 14, 2009 12:17 AM by dwahlin

Bill:

I'm just setting up the sequel. :-) I'll try to put together a post on that soon but to be honest I go with an extremely simple concept there.  I have a static EventBus class (multiple classes actually) and it simply defines the events and the OnEventName method.  So, a UserControl or ViewModel (either one) could raise an event using OnEventName and the listener can attach to the event.  Very simple overall, but that's exactly how I like to keep it for maintenance.

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Wednesday, December 16, 2009 11:21 AM by Bo Mortensen

One of the best "Getting started with MVVM" posts I've seen in a long time :) thumbs up!

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Thursday, December 17, 2009 11:45 PM by dwahlin

Thanks Bo...glad you found it useful.

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Tuesday, December 22, 2009 2:52 PM by Ian

Hello Dan.

This is Ian from Recovery Innovations. Hope you still remember me. Anyway, very great work - simple and straight forward. All implementations should be like this. :)

Thanks again for the great work.

# re: Getting Started with the MVVM Pattern in Silverlight Applications

Thursday, December 24, 2009 3:47 AM by dwahlin

Ian:

Yep...defintely remember you.  Glad you found the post useful and hope everything is going well your way. Thanks for taking the time to comment. :-)

# Excursus: Supervising Controller Pattern &laquo; AJ&#8217;s blog

Friday, January 01, 2010 8:36 AM by Excursus: Supervising Controller Pattern « AJ’s blog

Pingback from  Excursus: Supervising Controller Pattern &laquo; AJ&#8217;s blog

# MVVM needs (re)definition &laquo; AJ&#8217;s blog

Friday, January 01, 2010 8:44 AM by MVVM needs (re)definition « AJ’s blog

Pingback from  MVVM needs (re)definition &laquo; AJ&#8217;s blog

# Using Autofac as an IoC Container in Silverlight Applications

Sunday, January 03, 2010 3:31 AM by Dan Wahlin's WebLog

The subject of Dependency Injection (DI) and Inversion of Control (IoC) containers has received a lot

# Using Autofac as an IoC Container in Silverlight Applications | I love .NET!

Pingback from  Using Autofac as an IoC Container in Silverlight Applications | I love .NET!

# Slides and Code from my Silverlight MVVM Talk at DevConnections

Sunday, April 18, 2010 8:20 PM by Dan Wahlin's WebLog

I had a great time at the DevConnections conference in Las Vegas this year where Visual Studio 2010 and

# http://weblogs.asp.net/dwahlin/archive/2009/12/08/getting-started-with-the-mvvm-pattern-in-silverlight-applications.aspx

Tuesday, April 20, 2010 6:03 AM by Twitter Mirror

http://weblogs. asp.net /dwahlin/archive/2009/12/08/getting-started-with-the-mvvm-pattern-in-silverlight

# MVVM article &laquo; Step Into The &#039;Light

Tuesday, June 08, 2010 3:30 PM by MVVM article « Step Into The 'Light

Pingback from  MVVM article &laquo; Step Into The &#039;Light

# Understanding the Role of Commanding in Silverlight 4 Applications

Friday, August 06, 2010 6:35 PM by Dan Wahlin's WebLog

I’ve had the opportunity to give a lot of presentations on the Model-View-ViewModel (MVVM) lately both

# El patr??n MVVM y Windows Phone 7&#8230; &mdash; joseangelfernandez.es

Pingback from  El patr??n MVVM y Windows Phone 7&#8230; &mdash; joseangelfernandez.es

# Windows Phone – MVVM I

Thursday, November 11, 2010 11:37 AM by Blog de Oskar Alvarez

Dentro de la serie de Windows Phone el otro día vimos como instalar las herramientas para su desarrollo

# Getting started with Windows Phone 7 application development &laquo; Tech Hike

Pingback from  Getting started with Windows Phone 7 application development &laquo; Tech Hike

# Getting Started with the MVVM Pattern in Silverlight Applications

Monday, February 28, 2011 9:56 PM by Microsoft Weblogs

Wondering what all the hype is about MVVM and whether or not you should integrate it into your Silverlight

# MVVM f??r Neueinsteiger &laquo; Pocketmobile&#039;s Blog

Tuesday, March 01, 2011 12:44 AM by MVVM f??r Neueinsteiger « Pocketmobile's Blog

Pingback from  MVVM f??r Neueinsteiger &laquo; Pocketmobile&#039;s Blog

# MVVM Pattern in Silverlight

Sunday, April 24, 2011 5:56 AM by Blog J.Schweiss

MVVM Pattern in Silverlight

# Learning Silverlight 4

Monday, April 25, 2011 5:13 PM by Heaps of XAML

Learning Silverlight 4

# Silverlight Blendability with MVVM &laquo; Conficient Blog

Pingback from  Silverlight Blendability with MVVM &laquo; Conficient Blog

# DevConnections Konferenz in Karslruhe 2011 &#8211; Tag 1 &laquo; Wissenswertes

Pingback from  DevConnections Konferenz in Karslruhe 2011 &#8211; Tag 1 &laquo;  Wissenswertes

# Getting Started with the MVVM Pattern in Silverlight Applications

Thursday, July 07, 2011 11:33 AM by The Silverlight Blog

Wondering what all the hype is about MVVM and whether or not you should integrate it into your Silverlight

# MVVM and Service Agent

Wednesday, August 10, 2011 5:19 AM by Digest about software

MVVM and Service Agent

# Developing Mobile Dashboards for ComponentArt Dashboard Server

Friday, October 14, 2011 4:32 PM by For the Love of Data

What is ComponentArt Dashboard Server? Since our recent announcement of ComponentArt Dashboard Server

# Calling All Windows Phone Student Developers: Get Started Building your WP7 Apps & Games and WIN BIG

Saturday, November 19, 2011 10:56 AM by Tara's Developer Ramblings from the Dorm

For those of you interested in building an Windows Phone app or putting the finishing touches on your

# .NET Callback Delegate Syntax in MVC for MVVM | DIGG LINK

Wednesday, December 14, 2011 9:34 PM by .NET Callback Delegate Syntax in MVC for MVVM | DIGG LINK

Pingback from  .NET Callback Delegate Syntax in MVC for MVVM | DIGG LINK

# Windows Phone University Phone Camps + Some great Resources and Samples for teaching and learning

Monday, January 23, 2012 7:20 AM by Microsoft UK Faculty Connection

&#160; For those of you interested in building Windows Phone app’s or putting the finishing touches on

# Building Interactive Maps with Silverlight and Bing Maps&ndash;Part 2 | blog.credera.com

Pingback from  Building Interactive Maps with Silverlight and Bing Maps&ndash;Part 2  |  blog.credera.com

# MVVM Light Toolkit &#8212; GalaSoft - nonocast

Monday, April 16, 2012 2:04 AM by MVVM Light Toolkit — GalaSoft - nonocast

Pingback from  MVVM Light Toolkit &#8212; GalaSoft - nonocast

# Getting Started with the MVVM Pattern in Silverlight Applications | dotNuts

Pingback from  Getting Started with the MVVM Pattern in Silverlight Applications | dotNuts