Not being able to find a simple MVVM walkthrough I really liked, I created this simple example for those just wanting to see quickly how to connect the dots.

It doesn’t do anything fancy (just uses some basic databindings and a single command) but if you are just looking for a quick example of how to hook the View to the ViewModel hopefully this will help.

The app

This example is based on a simple WPF application. You basically enter some data and it populates a label.

How it all works

MVVM (a variant of MVC and MVP) uses WPF databinding to keep UI controls and Model elements in sync.

This clear separation of concerns makes applications more testable, and well as eliminating a lot of the event plumbing you would otherwise need to keep all your controls up-to-date.

Here’s a short walk through of what’s going on.

The View

The XAML View is where we put our UI controls and define how they get hooked up to our ViewModel. The beauty of MVVM is that it takes care of a lot of the plumbing for connecting keeping the View and ViewModel in sync (if one changes the other will be notified).

InvoiceView.xaml.cs

<UserControl x:Class="MvvmSimple2.InvoiceView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" IsEnabled="{Binding Enabled}"
             d:DesignHeight="300" d:DesignWidth="300">
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Height="20" Margin="5" Width="100">InvoiceNumber</TextBlock>
            <TextBox Height="20" Width="100" Margin="5" Text="{Binding Path=Invoice.Id}"></TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Height="20" Margin="5" Width="100">Receiver</TextBlock>
            <TextBox Height="20" Width="100" Margin="5" Text="{Binding Path=Invoice.Receiver}"></TextBox>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <Button Command="{Binding SaveCommand}" Margin="5" Width="75" CommandParameter="{Binding}">Save</Button>
        </StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock  Margin="5" Text="{Binding DisplayMessage}" />
        </StackPanel>
    </StackPanel>
</UserControl>

Big things to note here are how the View and ViewModel get connected, and how the UI controls get databound to the ViewModel properties. Let’s look at those now.

How do I hook this View up to my MainWindow?

You can connect your MainWindow.xaml to your newly created View by doing the following:

MainWindow.xaml

<Window x:Class="MvvmSimple2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
        <ContentControl Content="{Binding InvoiceView}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
    </StackPanel>
</Window>

The bit of magic we are interested in is this line:

<ContentControl Content="{Binding InvoiceView}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />

Here we are ‘binding’ our Content to our InvoiceView user control. If you are wondering how MainWindow.xaml knows what Binding InvoiceView is, that gets hooked up in our code behind as follows:

MainWindow.xaml.cs

using System.Windows;

namespace MvvmSimple2
{
    public partial class MainWindow : Window
    {
        private InvoiceView invoiceView;

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            this.invoiceView = new InvoiceView();
        }

        public InvoiceView InvoiceView { get { return this.invoiceView; } }
    }
}

There is a couple of things going on here.

First we are setting ourselves (MainWindow.xaml.cs) as the DataContext for ourselves.

That means when we do this …

<ContentControl Content="{Binding InvoiceView}" ...

MainWindow.xaml knows to ask itself for what InvoiceView is via it’s property getter:

 public InvoiceView InvoiceView { get { return this.invoiceView; } }

This getter of course returns our InvoiceView model. That’s how we get our ViewModel into our MainWindow.

How do I connect my View to the ViewModel?

You can do this in two ways.

You can do it programmatically in your xaml code behind as shown below:

InvoiceView.xaml.cs

using System.Windows.Controls;

namespace MvvmSimple2
{
    public partial class InvoiceView : UserControl
    {
        public InvoiceView()
        {
            InitializeComponent();
            DataContext = new InvoiceViewModel(); 
        }
    }
}

Or you can hook it up directly in your xaml.

InvoiceView.xaml

<UserControl x:Class="MvvmSimple2.InvoiceView"
             xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
	      ...
             d:DesignHeight="300" d:DesignWidth="300">
    <UserControl.DataContext>
        <MvvmSimple2:InvoiceViewModel/>
    </UserControl.DataContext>

Either way will work. I don’t have a strong preference yet for one over the other. Just be consistent and do it the same way everywhere in your app.

How do I bind my View controls to my ViewModel?

You do this using WPF databindings.

Databindings are the magic plumbing that make MVVM possible. By binding our View UI controls to properties on our ViewModels, when something changes in one, we can be notified about it in the other.

Because we already bound our whole View to the InvoiceModelView.cs in the previous step, we can access any property the ViewModel exposes.

Our ViewModel exposes the following properties:

public class InvoiceViewModel : INotifyPropertyChanged
        private string displayMessage;
        private Invoice invoice;
        private ICommand saveCommand;

Don’t worry. We’ll get to the ViewModel shortly. Just understand for now that when we do this on our view:

DataContext = new InvoiceViewModel();

We get access to all the ViewModel properties in our view. That’s why we can do neat things like hook up commands (which are objects in themselves) to buttons. Like this:

<Button Command="{Binding SaveCommand}" CommandParameter="{Binding}">Save</Button>

There’s one bit of magic going on above that wasn’t obvious to me the first time I saw it. It’s this bit:

CommandParameter="{Binding}"

By passing the {Binding} as part of the CommandParameter we are passing the whole ViewModel (InvoiceViewModel in this case) to our command. Why would we want to do that?

Well by doing that we can gain access to all the properties that hang off our ViewModel in our command. So if we need some values from the View, they are there for us.

The ViewModel

The ViewModel is where we define which properties we want to expose to our View (and do things with our Model’s).

using System;
using System.ComponentModel;
using System.Windows.Input;

namespace MvvmSimple2
{
    public class InvoiceViewModel : INotifyPropertyChanged
    {
        private string displayMessage;
        private Invoice invoice;
        private ICommand saveCommand;

        public InvoiceViewModel()
        {
            invoice = new Invoice(); // important – must initialize model
        }

        public string DisplayMessage
        {
            get { return displayMessage; }
            set
            {
                if (displayMessage != value)
                {
                    displayMessage = value;
                    OnPropertyChanged("DisplayMessage");
                }
            }
        }

        public Invoice Invoice
        {
            get { return invoice; }
        }

        public ICommand SaveCommand
        {
            get
            {
                if (saveCommand == null)
                    saveCommand = new Saver();
                return saveCommand;
            }
            set { saveCommand = value; }
        }

        protected class Saver : ICommand
        {
            public bool CanExecute(object parameter)
            {
                return true;
            }
            public event EventHandler CanExecuteChanged;
            public void Execute(object parameter)
            {
		  // can do this because we did 
		  // CommandParameter="{Binding}"
		  // with the databinding in our view
                InvoiceViewModel viewModel = (InvoiceViewModel)parameter; 

                string message = string.Format("Thanks for creating invoice: {0} {1}", 
                                               viewModel.Invoice.Id,
                                               viewModel.Invoice.Receiver);
                viewModel.DisplayMessage = message;

            }
        }

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

The first thing to note right at the top is this interface:

    public class InvoiceViewModel : INotifyPropertyChanged

It gets used a lot in MVVM. It’s how we notify our Views when something has changed (we fire properties that the View databinds to).

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

Then where one of our properties changes (like we set our DisplayMessage) the View will be notified of that change.

        public string DisplayMessage
        {
            get { return displayMessage; }
            set
            {
                if (displayMessage != value)
                {
                    displayMessage = value;
                    OnPropertyChanged("DisplayMessage");
                }
            }
        }

How does the save command work?

The SaveCommand is cool because it’s an object unto itself. We instantiate it like this:

public ICommand SaveCommand
        {
            get
            {
                if (saveCommand == null)
                    saveCommand = new Saver();
                return saveCommand;
            }
            set { saveCommand = value; }
        }

And define it like this:

        protected class Saver : ICommand
        {
            public bool CanExecute(object parameter)
            {
                return true;
            }
            public event EventHandler CanExecuteChanged;
            public void Execute(object parameter)
            {
                InvoiceViewModel viewModel = (InvoiceViewModel)parameter; // magic! explain how this got populated
                string message = string.Format("Thanks for creating invoice: {0} {1}", 
                                               viewModel.Invoice.Id,
                                               viewModel.Invoice.Receiver);
                viewModel.DisplayMessage = message;

            }
        }

Commands in MVVM are defined using the ICommand interface which basically defines methods for determining whether a command can be fired, and what it does when you do.

The magic here is in the Execute method which we talked about earlier. Here we receive a parameter object, but because we passed in the ViewModel with that CommandParamater databinding in our View (as discussed above), we get the whole thing here which we can cast into our ViewModel.

Then when we set the DisplayMessage property on the ViewModel:

viewModel.DisplayMessage = message;

and an events fires and updates our View.

The Model

Invoice.cs

using System.ComponentModel;

namespace MvvmSimple2
{
    public class Invoice : INotifyPropertyChanged
    {
        private int id;
        private string receiver;

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, 
                             new PropertyChangedEventArgs(propertyName));
            }
        }

        public int Id
        {
            get { return id; }
            set
            {
                if (id != value)
                {
                    id = value;
                    OnPropertyChanged("Id");
                }
            }
        }

        public string Receiver
        {
            get { return receiver; }
            set
            {
                receiver = value;
                OnPropertyChanged("Receiver");
            }
        }
    }
}

It basically defines property notification on its properties (Id and Receiver) and gets exposed through the ViewModel as follows:

InvoiceViewModel.cs

        public Invoice Invoice
        {
            get { return invoice; }
        }

Our model got databound to the View UI controls like this:

InvoiceView.xaml

<TextBox ... Text="{Binding Path=Invoice.Id}"></TextBox>
<TextBox ... Text="{Binding Path=Invoice.Receiver}"></TextBox>

So when you type anything into those textboxes the Invoice Model properties pick that up and notify anyone that’s interested that they’ve changed.

Invoice.cs

        public int Id
        {
            get { return id; }
            set
            {
                if (id != value)
                {
                    id = value;
                    OnPropertyChanged("Id");
                }
            }
        }

Trouble shooting

How come when I rename Invoice to InvoiceModel the app stops working?

Say you wanted to rename Invoice to InvoiceModel (to be consistent with the ViewModel and View naming conventions).

Tools like resharper make refactoring easy but it’s easy to forgot to update the bindings in your ViewModels.

InvoiceView.xaml

<TextBox Height="20" Width="100" Margin="5" Text="{Binding Path=InvoiceModel.Id}"></TextBox>

This is one of the things you have to be careful of when working with MVVM. When you rename anything involved in databinding, you need to make sure you get all the mappings.

And that’s basically MVVM in a nutshell!

Don’t worry if you MVVM a bit confusing at first. Databinding, event notification, and Commands can be a lot to absorb all at once if you are new to WPF.

A great book for WPF in general is WPF 4 Unleashed.

But hopefully this simple example will show you it’s not that bad once you connect the dots, and give you some ideas on other things to try.

Have fun!

Download source: MvvmSimple21.pdf
(right click -> Save link as -> rename to MvvmSimple21.zip – wordpress limitation)

Update: Jan 13 2011 – Added the section “How do I hook this View up to my MainWindow?”