Beginning MVVM: The Basics

WPF and Silverlight experts talk a lot about the new Model-View-ViewModel pattern these days. The powerful databinding support in WPF framework provides the basis for MVVM pattern. In this post, I will be highlighting some points that beginners may need to know to start learning MVVM.

To start with MVVM, you must know the basics of WPF/Silverlight databinding and how to data-bind controls using XAML constructs. The thing to note is that if you data-bind a UI control to an object (using the DataContext dependency property), then all of the public properties of that data-object are available to the child controls. In MVVM, the view (a UI control/page) is data-bound to a ViewModel (a simple C# class). The ViewModel exposes all the data and commands the View needs via properties. The View, then declaratively binds its UI controls to corresponding properties and commands of the ViewModel via XAML constructs.

As concepts are more clarified through examples, I am presenting a very simple example. Lets build a Silverlight MVVM version for this UI:
mvvm-picture1

The Listbox presents a list of persons and the right section presents the details of a selected person. To start with MVVM, we will make a ViewModel class containing two properties: a PersonList property that will be providing list of persons for the Listbox, and a SelectedPerson property that will contain the reference to the selected person. Here’s a crud implementation for the class:

public class PersonViewModel : System.ComponentModel.INotifyPropertyChanged
{
    ObservableCollection<Person> personList;
    Person selectedPerson;

    public PersonViewModel()
    {
        //populate some sample data
        personList = new ObservableCollection<Person>()
        {
            new Person(){Name="Syed Mehroz Alam", Age=10, City="Karachi", Country="Pakistan"},
            new Person(){Name="Zinedine Zidane", Age=20, City="Marseille", Country="France"},
            new Person(){Name="Ronaldinho", Age=30, City="Porto Alegre", Country="Brazil"},
            new Person(){Name="John Smith", Age=40, City="Washington", Country="USA"}
        };
    }

    #region Properties

    public ObservableCollection<Person> PersonList
    {
        get { return personList; }
    }

    public Person SelectedPerson
    {
        get { return selectedPerson; }
        set
        {
            selectedPerson = value;
            RaisePropertyChanged("SelectedPerson");
        }
    }

    #endregion

    #region INotifyPropertyChanged Members

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
    private void RaisePropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
    }

    #endregion
}

Now we have this View-Model ready to be consumed by a View. So in a new UserControl, we will instantiate the ViewModel class through XAML in the resources section and will data-bind the View to it using DataContext property of the main control of the View, in our case, a Grid named LayoutRoot. Since the LayoutRoot is data-bound to the ViewModel class, we can use its public properties as the DataSources of our other controls in the View. For our example, we will assign Listbox’s ItemSource to ViewModel.PersonList property and Listbox’s SelectedItem to ViewModel.SelectedPerson property. The right section will be bound to the SelectedPerson and will contain TextBoxes for displaying details of that person. Here’s the XAML code:

<UserControl x:Class="MVVMExample1.View.PersonView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:viewmodel="clr-namespace:MVVMExample1.ViewModel"
    >
    <UserControl.Resources>
        <viewmodel:PersonViewModel x:Key="ViewModel" />
    </UserControl.Resources>

    <!-- Databind the root control to the ViewModel class -->
    <!-- This way, all the public properties of ViewModel class become available to us -->
    <Grid x:Name="LayoutRoot" Background="White" DataContext="{StaticResource ViewModel}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="250" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>

        <!-- The listbox gets its ItemSource from ViewModel.PersonList property -->
        <!-- Also, the SelectedItem is bound to ViewModel.SelectedPerson property -->
        <ListBox Grid.Column="0" Margin="5"
                 ItemsSource="{Binding PersonList}"
                 DisplayMemberPath="Name"
                 SelectedItem="{Binding SelectedPerson, Mode=TwoWay}"
                 />

        <!-- Databind the right section to ViewModel.SelectedPerson property -->
        <Grid x:Name="PersonDetails" Grid.Column="1" DataContext="{Binding SelectedPerson}" Margin="5" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100" />
            <ColumnDefinition Width="150" />
        </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="30" />
                <RowDefinition Height="20" />
                <RowDefinition Height="20" />
                <RowDefinition Height="20" />
                <RowDefinition Height="20" />
            </Grid.RowDefinitions>
            <TextBlock Grid.Row="0" Grid.ColumnSpan="2" Text="Person Details" FontSize="15" />

            <TextBlock Grid.Row="1" Grid.Column="0" Text="Name" />
            <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Name, Mode=TwoWay}" />

            <TextBlock Grid.Row="2" Grid.Column="0" Text="Age" />
            <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Age, Mode=TwoWay}" />

            <TextBlock Grid.Row="3" Grid.Column="0" Text="City" />
            <TextBox Grid.Row="3" Grid.Column="1" Text="{Binding City, Mode=TwoWay}" />

            <TextBlock Grid.Row="4" Grid.Column="0" Text="Country" />
            <TextBox Grid.Row="4" Grid.Column="1" Text="{Binding Country, Mode=TwoWay}" />
        </Grid>

    </Grid>
</UserControl>

That’s all, our sample application is ready to be run. Observe how selecting a person updates the person details section. Also observe that the databindings are TwoWay and changing the name of a person in the details section is reflected in the ListBox panel as well.

Note that in Silverlight, we do not have built-in support for commands and triggers like WPF. So in order to execute some code upon a button click, we will either need manual hooking of the button’s Click event, a separate third party extension(e.g. SLExtensions, Prism or SilverlightFX) or make our own implementation. More on this in some later post.

Notice that MVVM seems difficult at first, but as soon as you create your first UI using this pattern, you will find yourself thinking your application in terms of Dependency Properties and IValueConverters. Beware, MVVM is quite addictive. Karl Shifflett presents some great MVVM resources on this page. Be sure to bookmark that page for new MVVM stuff.

The source code for the example UI we discussed can be downloaded here. The file needs to be renamed to .zip for extraction. This is “WordPress File Download Pattern” :)

About these ads

23 Responses to “Beginning MVVM: The Basics”

  1. Niladri Biswas Says:

    Nice example and well description…

    I found it helpfull…. please put more articlers on this so that peoples like me can be benefited

  2. kumar Says:

    Nice example, its helped me understanding mvvm easily.

    Thanks.

  3. Thoughts on MVVM and Threads « Tales from a Trading Desk Says:

    [...] Person list exposed in this sample is basically the domain model. In which case all the ViewModel is providing is the SelectedPerson, [...]

  4. Tanveer Badar Says:

    The topic is discussed at much detail on http://blogs.msdn.com/johngossman the man who invented the concept.

  5. Syed Mehroz Alam Says:

    Of course, he is the pioneer of the MVVM pattern. Here’s his original post that he wrote in 2005: http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx

  6. Arxisos Says:

    Thank you for this great article. Now i understand MVVM much better!

  7. B Says:

    Hey, Really good article…..

  8. Calabonga Says:

    Can you show so simple example for ICommand for MVVM?

  9. Syed Mehroz Alam Says:

    Calabonga,

    John Papa has a great and simple example for using ICommand in Silverlight 4. Have a look here.

  10. Pallavi Says:

    Thanks…Its a nice article for beginners

  11. Debashish Gupta Says:

    Hi Mehroz ,
    I am calling the above view from page.xaml so i wanted to change the binding like this.
    DataContext=”{StaticResource ViewModel}” iNSTED I USE
    DataContext=”{Binding}”

    But it dose not work.
    ——————-Page.xaml————————-

    ———————–Page.xmal.cs—————————
    void Page_Loaded(object sender, RoutedEventArgs e)
    {
    PersonViewModel pdata = new PersonViewModel();
    pdata.FetchPersons();
    PersonDataView.DataContext = pdata.PersonList;
    }

    Regards
    Debashish

  12. Syed Mehroz Alam Says:

    Debashish,

    In your code, you are assigning pdata.PersonList as your view’s DataContext. You need to use pdata as your datacontext like this:

    void Page_Loaded(object sender, RoutedEventArgs e)
    {
      PersonViewModel pdata = new PersonViewModel(); 
      pdata.FetchPersons();
      PersonDataView.DataContext = pdata;
    }
    
  13. bhavana Says:

    Excellent example!! Simple and easy to understand. Thank you. Can we move forward by showing how we use the Model class of MVVM?

  14. Pallavi Says:

    please provide more easy to understand stuff

  15. Thanigainathan Says:

    HI,

    Thanks for sharing this very informative article.

    One thing I noted was the Grid Context setting was not correct here . But the download had the correct code.

    Wrong:
    DataContext=”{StaticResource ViewModel}”

    Correct:
    DataContext=”{Binding Source={StaticResource modelpres}}”

    Thanks,
    Thanigainathan.S

  16. praveen Says:

    nice example it helps me a lot

  17. M Shoaib Sheikh Says:

    Extreemly easy to understand MVVM pattern Mehroz bhai the way you explained it …Cheers !

  18. Tily Says:

    Hi,

    It’s possible to make a button next to the list, and when you click that button the Personals Details appears in the right side?

  19. Andrei Says:

    Thanks, man, for good explain

  20. Tom Says:

    Hi there.

    This is a very well written article. However it is NOT MVVM…. Where is the model?

    This article only covers the ‘VM’ of MVVM.

  21. ashek Says:

    Nice Pick Tom….


Leave a Reply

Fill in your details below or click an icon to log in:

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

Follow

Get every new post delivered to your Inbox.

Join 56 other followers

%d bloggers like this: