Skip Navigation LinksHome / Articles / View Article

Model – View – ViewModel in Silverlight

+ Add to SilverlightShow Favorites
25 comments   /   posted by Pencho Popadiyn on Mar 11, 2009
(17 votes)

1. Introduction

Whatever software application you want to create, the most important problem that must be solved is the tight coupling. Mixing one layer with another is a very common mistake and it is the main reason for your application to be tightly coupled. For example: as a practical example in this article I will create a simple data entry application, which purpose is to load, create, edit, delete and save data. The most straightforward way to create the application is to put everything in the user interface (handling the button’s click events and writing the code there). It is the easiest way but it is far from the best. This will produce a low quality code and high complexity. And when the things are tightly coupled, one change can lead you into chasing breaking changes in the whole code. So the most important thing is to keep the layers separate, one layer – one responsibility. Yes, it is true, that creating an application with separate tiers requires additional work, but this may save you a headache in the future.

The most famous solutions and approaches (patterns) for creating a multi layer application are the MVC and MVP patterns. Since Silverlight does not require reinventing the wheel, these patterns and practices can be applied with great success when you create a Silverlight application. In previous articles I showed you how the Model-View-Presenter (MVP) pattern and the Model-View-Controller (MVC) pattern can be used in Silverlight. Today I decided to continue and to present you another pattern – it is the Model-View-ViewModel (MVVM). MVVM is tailor-made for WPF and it is an adaptation of the MVC and MVP.

View live demo

Download source

2. Introducing the Model – View – ViewModel pattern

For the first time the MVVM pattern has been unveiled by John Gossman in 2005. Since the MVVM is a very similar to the MVC (MVP), let’s see what are the differences and the resemblances.

As you can guess, the pattern separates responsibilities across three components:

  • The model is responsible for business behaviors, state management. It is very important because it wraps the access to the data.
  • The view is responsible only for the rendering of the UI elements.

These are the common things, and they should not be new to you if you are already familiar with the MVC or MVP patterns. The third component is the one that brings the difference. You probably remember that the role of the controller’s (presenter’s) is to ensure the interaction between the model and the view. One of the main characteristics of the MVVM pattern is that the third component – the ViewModel does not contain a reference to the view. Hmmm, but we expect the ViewModel to serve as a bridge between the model and the view, then how it will manage and update the view? When XAML came into our world a lot of things changed. One of them was the introduction of the declarative programming which saves us a lot of code and offers us a great flexibility, and an easy way to create animations, styling, and data bindings. Yes, the answer is data binding; this is the core of the MVVM pattern.

The bindings between the view and the ViewModel are possible because a ViewModel instance is set as a DataContext of a view. The view binds to properties on a ViewModel, which exposes data contained in model objects. When a property in the model is changed, then the new value is automatically propagated to the view through the data binding. The model is necessary to implement the INotifyPropertyChanged or the INotifyCollectionChanged interfaces.

3. Differences between WPF and Silverlight

As you will see in the practical example later in the article, one of the aspects that makes the MVVM a great pattern is the data binding infrastructure. By using a data binding, you get loose coupling between the view and the ViewModel and entirely avoid the need for writing code in the ViewModel in order to update the view. The binding system in WPF also supports input validation which is not offered in Silverlight. In WPF you can use the IDataErrorInfo interface. Another important difference between the two systems is that Silverlight does not support commands which will allow the view to directly consume the ViewModel functionality.

4. Practical example

In the next section I will present you a step by step example, which does not necessarily represent a real world example. It aims to help you understand how to implement the MVVM pattern. In a few words, the example represents a catalog with cars that offers you the standard functionalities for any CRUD application such as add, edit, delete, load and save.

4.1 The model

So let’s start with the model first. On the analogy of the MVC and MVP patterns the model in the MVVM is responsible for the business behavior, state management and data access. Since in the MVVM the data binding system is very important, the model must implement the INotifyPropertyChanged or INotifyCollectionChanged (Observable Collection) interface in order to bubble changes up the stack. In order to ensure the communication between the model and the view model we should create an interface for the model. This is good practice because later we could replace the model with other implementations (for example, testing purpose). You can see the interface for the model on the next diagram.

It contains various methods, properties and events that are required for data access or its manipulation. As you can see the business object Car implements the INotifyPropertyChanged interface. The CarsCollection type is a custom class which inherits from ObservableCollection<T>. Thus whenever we add or delete object(s) from the collection, the user interface will be automatically updated.

Now let’s take a look at the most important aspects of the model implementation. The method SaveChanges constructs a new XDocument and saves it in an xml file in your isolated storage.

 

XElement carsElement = new XElement( "cars" );
foreach ( Car c in cars )
{
    XElement carElement = new XElement( "car",
        new XAttribute( "id", c.Id ),
        new XAttribute( "brand", c.Brand ),
        new XAttribute( "model", c.Model ),
        new XAttribute( "producer", c.Producer ),
        new XAttribute( "productionDate", c.ProductionDate ),
        new XAttribute( "price", c.Price ),
        new XAttribute( "image", c.ImageUrl ) );
    carsElement.Add( carElement );
}
 
XDocument doc = new XDocument( carsElement );
 
using ( IsolatedStorageFile isoStore = IsolatedStorageFile.GetUserStoreForApplication() )
{
    using ( IsolatedStorageFileStream isoStream = 
        new IsolatedStorageFileStream( "CarsData.xml", FileMode.OpenOrCreate, 
                                        FileAccess.Write, 
                                        isoStore ) )
    {
        doc.Save( isoStream );
        isoStream.Flush();
    }
}

 

The method LoadCars will first try to load the data from your isolated storage. If it fails then it will load the data from a default xml file which is attached in the application xap file.

var qry = ( from c in xDoc.Descendants( "car" )
        select Car.CreateNewCar(
           Int32.Parse( c.Attribute( "id" ).Value ),
           c.Attribute( "model" ).Value,
           c.Attribute( "brand" ).Value,
           c.Attribute( "producer" ).Value,
           DateTime.Parse( c.Attribute( "productionDate" ).Value ),
           Decimal.Parse( c.Attribute( "price" ).Value ),
           c.Attribute( "image" ).Value ) );
 
return qry.ToArray();

Whenever the user is adding a new car or editing an existing we should validate the data. Silverlight does not support the IDataErrorInfo interface, that’s why we should create some simple custom validation. This is the work of the ValidateCar method.

public static readonly List<string> PropertiesForValidation = new List<string>(
       new string[] { "Model", "Brand", "Producer", "Price", "ProductionDate" } );
 
public string ValidateCar( Car c )
{
    string error = null;
 
    error = this.ValidateModel( c );
    if ( error != null )
        return error;
 
    error = this.ValidateBrand( c );
    if ( error != null )
        return error;
 
    error = this.ValidateProducer( c );
    if ( error != null )
        return error;
 
    error = this.ValidatePrice( c );
    if ( error != null )
        return error;
 
    error = this.ValidateProductionDate( c );
    if ( error != null )
        return error;
 
    return error;
}

 

The AddCar and DeleteCar methods are pretty straightforward. The four events are used to notify the observers when the data is loaded and saved or something goes wrong.

4.2 View and view model

In our application we have a simple design that is used to browse and edit car information. You can see the main page on the next figure.

In order to create the view I used a standard controls from the Silverlight library (buttons, text blocks, text boxes, tab control and data grid). As you remember the view model does not contain a reference to the view. The connection between the components is realized through data binding. You can see the view model class on the next diagram.

The view model must meet the following requirements:

  • It has to expose a data bindable collection – this is the CarsCollection. It must be an ObservableCollection so any changes will be automatically reflected on the user interface.
  • Another important issue is to provide a default constructor. Otherwise if your view model object does not have a default constructor then when you start the application you will receive my favorite exception: AG_E_PARSER_UNKNOWN_TYPE

Once our view model meets these requirements, it is ready to be bound directly to the XAML. In order to implement the data binding you should create a new instance of the view model as a resource (in the resources of your view) and then to bind it to the main container (in our case this is a Grid). You can see the whole procedure on the next figures.

First we need a data bindable collection and default constructor:

public CarsViewModel() :
    base()
{
}
 
\\ Other properties and methods
 
public CarsCollection CarsCollection
{
    get { return this.CarModel.CarsCollection; }
}

Second we should declare a new instance of the view model in the resources of the view:

Third we should set bind the view model to the main container:

<Grid x:Name="LayoutRoot" Background="Transparent"
          DataContext="{Binding Path=CarsCollection, >
          Source={StaticResource CarsViewModelDS}}"
 
<!-- Insert here the child elements -->
 
</Grid>

Finally we should again use data binding to propagate the data source to our data grid (which will display the data). Here you can see the XAML mark up for our data grid.

<data:DataGrid x:Name="dgrWokrspace" 
   RowDetailsVisibilityMode="VisibleWhenSelected" AutoGenerateColumns="False"
   ItemsSource="{Binding}">
 
<data:DataGrid.Columns>
    <data:DataGridTextColumn Binding="{Binding Id}" Header="Id" IsReadOnly="True"/>
    <data:DataGridTextColumn Binding="{Binding Brand}" Header="Brand" IsReadOnly="True"/>
    <data:DataGridTextColumn Binding="{Binding Model}" Header="Model" IsReadOnly="True"/>
    <data:DataGridTextColumn Binding="{Binding Price,  Header="Price" IsReadOnly="True"/>
        Converter={StaticResource PriceConverter}}"
    <data:DataGridTextColumn Binding="{Binding ProductionDate,  Header="Production Date" 
        Converter={StaticResource DateTimeConverter}}"
        IsReadOnly="True"/>
    <data:DataGridTemplateColumn Header="Image" IsReadOnly="True">
        <data:DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <Image Width="40" Height="40" Source="{Binding ImageUrl}" 
                    Stretch="Fill"/>
            </DataTemplate>
        </data:DataGridTemplateColumn.CellTemplate>
    </data:DataGridTemplateColumn>
</data:DataGrid.Columns>
 
</data:DataGrid>

Now whenever the LoadCars method of the view model is invoked,the data grid will be automatically populated.

You can see the live demo here

5. Final words

In this article I showed you another design pattern that can be used in the software development. It is the Model – View – ViewModel pattern. The pattern is tailor – made for WPF. However, the pattern can be used with great success in Silverlight applications (despite of some limitations). The MVVM is a simple but extremely effective set of guidelines for designing and implementing a Silverlight/WPF application. Like the other two patterns, it allows you to create a strong separation between the presentation, behavior and data, making it easier to control and maintain each one of them.

Share


Comments

Comments RSS RSS
  • RE: Model – View – ViewModel in Silverlight  

    posted by Dennis on Mar 11, 2009 11:15

    I tried to launch the application in Visual Studio but i got 'System.StackOverflowException' occurred in System.Windows.Controls. Demo doesn't work either.

  • RE: Model – View – ViewModel in Silverlight  

    posted by ppopadiyn on Mar 11, 2009 11:44

    Hi Dennis

    Hmm i dont have any idea about the exception. Did you change anything in the solution or just try to start it?

  • RE: Model – View – ViewModel in Silverlight  

    posted by Dennis on Mar 11, 2009 12:49

    No I didn't. Actually the app is starting but fails after clicking View all cars and then Add new car.

    By the way after the application is started no cars are displayed (though CarsData.xml is not empty). The same behaviour is in the live demo (both in IE and FF). I think it's strange enough... Maybe there is a problem with my silverlight. But i just updated it a couple minutes ago from silverlight.net/GetStarted/

  • RE: Model – View – ViewModel in Silverlight  

    posted by ppopadiyn on Mar 11, 2009 14:24

    Hi Dennis

    This is very strange for me, I cant see any reason for that exception. By the way you reported that the exception appears in System.Windows.Controls. The problem is that namespace is from the Silverlight framework (plugin). That lets me to think that the problem may be in your plugin (probably it is not installed correctly). The only advice that I can give you is uninstall and reinstall the plugin. Also that you can try to create an entirely new Silverligth solution, add a reference to the System.Windows.Controls and System.Windows.Controls.Data dlls, include those namespaces in your code behind file and try to start. What will be the result now?

  • RE: Model – View – ViewModel in Silverlight  

    posted by Matthew on Mar 12, 2009 06:37

    Hi Pencho,

    Nice article providing a brief overview of MVVM and the benefits it provides. Unfortunately, like Dennis i am having the same problem running the application. I need to click "View all cars" before "Add new car" is enabled and once i click Add new car, my browser shuts downs completely (no error, no exception, no nothing). I'm using Vista Home Premium SP1, Firefox 3.0.5 and SIlverlight 2.0.40115.0.

    Matthew

  • RE: Model – View – ViewModel in Silverlight  

    posted by ppopadiyn on Mar 12, 2009 08:17

    Hi Matthew

    Yes you need to click first "View all cars" before "Add new car" - this is an application logic. But about the second problem I dont have any idea, what can cause your problems. My colleagues tested the demo (on different machines with Vista and XP OS and latest Silverlight version), but no exceptions or problems occur. When you click "View all cars" the application will try to read an .xml file which is build in the xap package. With extremely simple LINQ query. That is very strange for me !

  • RE: Model – View – ViewModel in Silverlight  

    posted by ppopadiyn on Mar 12, 2009 08:51

    Hello guys

    I am terribly sorry about the inconvenience. I found the problem, it was one of the my favourites - a culture problem. I fixed it. Please keep in mind, that before to test the demo again, clear your browser's cache !!! I hope no more problem will occur ;)

  • RE: Model – View – ViewModel in Silverlight  

    posted by Dennis on Mar 12, 2009 09:30

    Hello Pencho

    Mmm... now I'm able to see the list of cars! And even edit two of them (#3 and #4, the ones without Chinese hieroglyphs in name? :))

    Unfortunately, for other actions the problem remains

  • RE: Model – View – ViewModel in Silverlight  

    posted by Martin on Mar 12, 2009 11:13

    Hi,

    I think the problem relates to the databinding on ProductionDate in DetailsPage.xaml. I found that binding to SelectedDate (only) works OK.

     

    <basics:DatePicker Margin="8,0,8,0" x:Name="dtpProductionDate" SelectedDate="{Binding Mode=TwoWay, Path=ProductionDate}" />

    Thanks,

    Martin

  • RE: Model – View – ViewModel in Silverlight  

    posted by ppopadiyn on Mar 12, 2009 12:48

    Hi guys

    As Martin said, the problem is a combination from the DateTimePicker control, the data binding and the different cultures. I will try to fix it during the weekend.

  • RE: Model – View – ViewModel in Silverlight  

    posted by silverlight_newbie on Mar 12, 2009 16:04

    Hi, in my oppinion this is closer to ASP.NET MVC pattern than to MVP pattern?

    What is your oppinion? IMHO model is the same, controller is _almost_ the same as ViewModel but isn't running any View, and View has changed a little, but at least there isn't any business logic just view logic via declarative binding. Nicely decoupled.

     

    What is your oppinion? Which one do you prefer to use, MVP or MVVM?

    I am completely ASP.NET MVC addict so I am looking for something similar to convert my project and learn silverlight in painless way. Thanks!

  • RE: Model – View – ViewModel in Silverlight  

    posted by ppopadiyn on Mar 12, 2009 17:24

    Hi silverlight_newbie

    Since the MVVM is an adaptation of the MVC and MVP thare are a lot in common. In fact the differences are matter of details in the implementation (as you said - the ViewModel isn't running any view but the controller is; if we take the MVP - there is an additional interface for the view and two possible way for updating the view). The differences are in the details. There are so many modifications of these patterns, that for me is extremely difficult to give a strong definition for each of them. I don't have partiality to any of these patterns. I think that the MVVM is slightly  better here in Silverlight because of the binding system (which really saves us a lot of code). But sometimes my choice depends on my mood :). Maybe you should try each of them in real application and to see which is most suitable for you. I suggest when you have free time, to take a look at the MVVM implementation in WPF and to see its real power (which is reduced in silverlight due to some lack of functionality). There, in WPF some features such as commands, triggers, properties validation make the MVVM pattern real monster.

    Good luck in the world of Silverlight

  • RE: Model – View – ViewModel in Silverlight  

    posted by vidalsasoon on Mar 15, 2009 18:33
    Could this somehow be applied to ADO.NET Data Services + Silverlight?
  • RE: Model – View – ViewModel in Silverlight  

    posted by ppopadiyn on Mar 16, 2009 02:50
    Hi vidalsasoon

    Yes you could use ADO.NET Data Services (or any other type of data access). The only thing you should do is to provide an appropriate implementation of the LoadData() and SaveData() methods.
  • RE: Model – View – ViewModel in Silverlight  

    posted by Hanuman on Apr 03, 2009 10:04
    Nice demo... i liked it. Expecting  more demos  from u  !!
  • RE: Model – View – ViewModel in Silverlight  

    posted by Yuvaraj Ilangovan on Apr 10, 2009 06:52

    Hi,

    It's really a nice article. You have made good effort to make us MVVM understandable with demo support. Thanks.

  • RE: Model – View – ViewModel in Silverlight  

    posted by Dharmindar on Apr 16, 2009 02:09

    Hi Dear,

    I have read ur article. It is a very good article. Once I saw a webcast of Joe Hummel On Architecting Destop Applications with MVC. And he explained the MVC architecture with the help of underlying patterns. He explained that MVC architecture in the simplest form consists of three patterns.

    Namely 1.Observer 2. Command 3.Adapter Patterns.

    It can have further more patterns.

    So If u can also explain it with the help of patterns.

    Thanks in Advance.

  • RE: Model – View – ViewModel in Silverlight  

    posted by ppopadiyn on Apr 16, 2009 14:03
    Hi Dharmindar

    Thank you for the perfect remark. The MVVM is an adaptation of the MVC pattern. The difference is in the implementation and what is true for the MVC is also almost true for the MVVM. As you say the both patterns are compound patterns (they consist of three or more patterns). The Observer pattern is pretty ambigous concept, because here in .NET we have "events" and if we consider the events as an implementation of the Observer pattern, then its true the Observer pattern is part from the MVC and MVVM. I must remark something here, in the canonical implementation of the MVC the events are used to transfer the data from the model to the view. But here in Silverlight/WPF, the MVVM uses a data binding (very powerfull feature) instead of events to transport the data from the model to the view. One pattern I can tell you with confidence that is used in the both patterns - it is the Strategy. Yes the Command is part from the MVC and MVVM (in WPF a "Command" has a special meanning).


  • RE: Model – View – ViewModel in Silverlight  

    posted by Dharmindar on Apr 21, 2009 08:03

    Hi Dear,

    You are right that eventing mechanism is the implementation of Observer Pattern. But one thing you just said in the canonical example is getting clear to me. The best approach is that your Model does not know your view in any case, so what you do put in between a controller to forward the request from Model to View and from View to Model. Controller portion of your MVC contains Command Patterns. It implements various commands which internally gets data from Model or sets data to Model. Then the View adapts those commands with the help of adapter patterns. And in this way View and Model are completely unaware of each other.

    There are situations when you find that loose coupling between View and Model does not worth that much then you avoid inturruptions between their direct communication.

    What do you think about this???

    Thanks... 

  • RE: Model – View – ViewModel in Silverlight  

    posted by ppopadiyn on Apr 23, 2009 13:23
    Hi Dharmindar

     I absolutely agree with you. As you said the most important thing is loose coupling between the view and model, thus we can reuse  (and in fact this is the heart of the OOP) the model with different views.


  • RE: Model – View – ViewModel in Silverlight  

    posted by mark on Sep 15, 2009 11:07
    Hi, I get an exception loading the data - due to invalid format on the time. In the file there is:

    productionDate

     

    ="3/5/2009"

     

    which is not an xml time is it?

     

     

  • RE: Model – View – ViewModel in Silverlight  

    posted by Jerome on Sep 24, 2009 13:50

    As a non-English user, I had to modify thedates in CarsData.xml (located in \MVVM_Silverlight\Data) sothat they're both valid as English and non-English dates.

    The new xml looks like this :

    <?xml version="1.0" encoding="utf-8" ?> 
    <cars> 
        <car id="1" brand="Porsche" model="911 GT3" producer="Porsche" productionDate="3/5/2009" price="106000" image="/Data/Images/Porshe_911_GT3.jpg"></car> 
        <car id="2" brand="Jaguar" model="XK" producer="Jaguar Cars" productionDate="6/10/2008" price="87700" image="/Data/Images/Jaguar_Xk.jpg"></car> 
        <car id="3" brand="Mercedes" model="GLK" producer="Daimler" productionDate="11/9/2007" price="35900" image="/Data/Images/Mercedes_Benc_GLK.jpg"></car> 
        <car id="4" brand="Aston Martin" model="Lagonda" producer="Aston Martin" productionDate="5/12/1977" price="150000" image="/Data/Images/Aston_Martin_Lagonda.JPG"></car> 
        <car id="5" brand="Trabant" model="-" producer="VEB Sachsenring" productionDate="8/7/1960" price="100" image="/Data/Images/Trabant.jpg"></car> 
        <car id="6" brand="Zaporozhets" model="ZAZ-965/965A" producer="ZAZ factory" productionDate="5/8/1960" price="100" image="/Data/Images/ZAZ-968.jpg"></car> 
    </cars> 
     

    But I came upon another problem : whenever I edit a line, I get aStackOverflowException apparently on ProductionDate in Car.cs on line 172 :

    temp( thisnew PropertyChangedEventArgs( info ) ); 

     

  • RE: Model – View – ViewModel in Silverlight  

    posted by e.g. on Oct 27, 2009 15:27
    Thanks! good Article
  • RE: Model – View – ViewModel in Silverlight  

    posted by Sergey on Dec 09, 2009 12:35

    The trouble is because the xml file has a specific speparator for en-US culture.

    The temporary solution is to change your current culture for main thread:

     

    namespace MVVM_Silverlight

    {

        public partial class Page : UserControl

        {

            public Page()

            {

                InitializeComponent();

                changeCulture();

            }

     

            void changeCulture()

            {

               System.Globalization.CultureInfo newCulture = new

                 System.Globalization.CultureInfo("en-US");

               System.Threading.Thread.CurrentThread.CurrentCulture = newCulture;

            }

        }

    }

    (If you have saved the data earlier, find CarsData.xml file in isolated storage and remove it because it may be empty.)

     

    To be honest, I don’t know what is the right way of solving this issue because I’ve had no practice with cross-cultural applications. But I wish to..

  • RE: Model – View – ViewModel in Silverlight  

    posted by Sergey on Dec 17, 2009 09:25

    Hi Pencho! I have a question.

    In this sample the ViewModel is just a proxy layer between the Model and the View, or as you said – it’s as a bridge between them. So, the question is very predictable: does the ViewModel justify the means of implementing and creating itself? In fact, we could bind the View to the Model without any bridge (without an additional code), and therefore we could get a simpler application which still has separate layers with single responsibility. But what’s the catch? May be in real applications the ViewModel has more sense than to be a useless bridge?

Add Comment

 
 

   
  
  
   
Please add 1 and 1 and type the answer here: