What is this “DataContext” you speak of?

July 14, 2012

I frequently see new WPF users confused about what the DataContext is, and how it is used. Hopefully, this can help clarify what the DataContext is, and how it is used.

What is the DataContext?

In WPF, there are two layers to an application: the UI layer and the Data layer.

The Data layer for an application starts out as null, and you can set it using the DataContext property. All UI objects will inherit their DataContext from their parent unless you specify otherwise.

When using the Model-View-ViewModel (MVVM) Design Pattern, the DataContext (Data Layer) is your application, while UI objects, like Buttons, Labels, DataGrids, and even Windows, are all just user-friendly items that allow a user to easily interact with the DataContext, which is your actual application and is typically comprised of ViewModels and Models.

How is it used

Whenever you do a basic binding in WPF, you are binding to the DataContext.

For example, when you write

<Label Name="myLabel" Content="{Binding Path=Name}" />

you are binding to myLabel.DataContext.Name, and not to myLabel.Name.

Other binding properties, such as ElementName or RelativeSource, can be used to tell the binding to lookup the property in something other than the current DataContext.

An Example

Lets start with a regular Window. Without setting the DataContext, the window still displays but there is no data behind it.

<Window x:Name="MyWindow" ...>
   ...
</Window>

Now suppose we set the DataContext to an object of type ClassA in the code-behind when this Window initializes:

public partial class MyWindow: Window
{
    public MyWindow()
    {
       InitializeComponent();
       this.DataContext = new ClassA();
    }
}

Now the data layer behind that the Window is an object of type ClassA.

If ClassA has a property called Name, I could add a Label to the window and bind it to Name property of the DataContext, and whatever value is stored in ClassA.Name would get displayed.

<Window x:Name="MyWindow" ...>
   <Label Content="{Binding Name}" />
</Window>

Now, suppose ClassA has a property called ClassB, and both classes have a property called Name. Here is a block of XAML which illustrates how the DataContext works. It also includes an example of how a control would refer to a property not in its own DataContext.

<!-- DataContext set to ClassA in initialization code -->
<Window x:Name="MyWindow"> 

    <!-- DataContext here is not specified, so it's inherited 
         from its parent's DataContext, which is ClassA -->
    <StackPanel> 

        <!-- DataContext inherited from parent, which is 
             ClassA, so this will display ClassA.Name -->
        <Label Content="{Binding Name}" />

         <!-- DataContext is still ClassA, however we are 
              setting it to ClassA.ClassB with a binding -->
        <StackPanel DataContext="{Binding ClassB}">

            <!-- DataContext inherited from parent, which is 
                 ClassB, so this will display ClassB.Name -->
            <Label Content="{Binding Name}" />

            <!-- DataContext is still ClassB, but we are 
                 binding to the Window's DataContext.Name, 
                 which is ClassA.Name -->
            <Label Content="{Binding 
                       ElementName=MyWindow, 
                       Path=DataContext.Name}" /> 
        </StackPanel>

        <!-- We've left the StackPanel with its DataContext 
             bound to ClassB, so this Label's DataContext 
             is ClassA (inherited from parent StackPanel), 
             and we are binding to ClassA.ClassB.Name -->
        <Label Content="{Binding ClassB.Name}" />
    </StackPanel>
</Window>

As you can see, all the basic bindings look for their value in the data layer (DataContext) of the UI object

Summary

So to summarize, WPF applications have two layers: the UI layer and the Data layer. The data layer for an application starts out as null, and can be set using the DataContext property. UI objects without a DataContext set will inherit their data layer from their parent object. Bindings are used to look up values in the data layer, and display them in the UI layer.

When using the MVVM design pattern, the data layer is your application, while the UI layer just provides a user-friendly way to access the Data layer.


Validating Business Rules in MVVM

January 22, 2012

I’ve always thought that raw data validation should occur in the data Model, while Business Rule validation should occur in the ViewModel.

For example, verifying that a UserName is no longer than X length long should occur in the data model, while verifying that the UserName is unique would occur in the ViewModel. The reason for this is that the User Model is simply a raw data object. It doesn’t contain any advanced functionality like database connectivity, or knowing about other User objects. It’s a selfish little thing which only cares about it’s own data.

Since I use IDataErrorInfo for my validation and like to expose the entire Model to the View from my ViewModel, this presents a problem. Using the above example, I could bind a TextBox to SelectedUser.UserName, and it would automatically show an ErrorTemplate if the string was too long, however it wouldn’t show an error template if the UserName already exists.

After some thought, I decided to add a Validation Delegate to my Models to solve this problem. This is a delegate which ViewModels can use to add Business Logic Validation to its Models.

In the above example, the UsersViewModel might look like this:

public class UsersViewModel
{
    // Keeping these generic to reduce code here, but they
    // should be full properties with PropertyChange notification
    public ObservableCollection<UserModel> UserCollection { get; set; }
    public UserModel SelectedUser { get; set; }

    public UsersViewModel()
    {
        UserCollection = DAL.GetAllUsers();

        // Add the validation delegate to the UserModels
        foreach(var user in UserCollection)
            user.AddValidationDelegate(ValidateUser);
    }

    // User Validation Delegate to verify UserName is unique
    private string ValidateUser(object sender, string propertyName)
    {
        if (propertyName == "UserName")
        {
            var user = (UserModel)sender;
            var existingCount = UserCollection.Count(p => 
                p.UserName == user.UserName && p.Id != user.Id);

            if (existingCount > 0)
                return "This username has already been taken";
        }
        return null;
    }
}

The actual implementation of my IDataErrorInfo on my Model class would look like the code below. It’s generic, so I usually put it into some kind of base class for my Models.


    #region IDataErrorInfo & Validation Members
    
    #region Validation Delegate
    
    public delegate string ValidationDelegate(
        object sender, string propertyName);
    
    private List<ValidationDelegate> _validationDelegates = new List<ValidationDelegate>();
    
    public void AddValidationDelegate(ValidationDelegate func)
    {
        _validationDelegates.Add(func);
    }

    public void RemoveValidationDelegate(ValidationDelegate func)
    {
        if (_validationDelegates.Contains(func))
            _validationDelegates.Remove(func);
    }
    
    #endregion // Validation Delegate
    
    #region IDataErrorInfo for binding errors
    
    string IDataErrorInfo.Error { get { return null; } }
    
    string IDataErrorInfo.this[string propertyName]
    {
        get { return this.GetValidationError(propertyName); }
    }
    
    public string GetValidationError(string propertyName)
    {
        string s = null;

        foreach (var func in _validationDelegates)
        {
            s = func(this, propertyName);
            if (s != null)
                return s;
        }
    
        return s;
    }
    
    #endregion // IDataErrorInfo for binding errors
    
    #endregion // IDataErrorInfo & Validation Members

The idea is that your Models should only contain raw data, therefore they should only validate raw data. This can include validating things like maximum lengths, required fields, and allowed characters. Business Logic, which includes business rules, should be validated in the ViewModel, and by exposing a Validation Delegate that they can subscribe to, this can happen.


Navigation with MVVM

December 18, 2011

When I first started out with MVVM, I was lost about how you should navigate between pages. I’m a firm believer in using ViewModels to do everything (unless it’s View-specific code), and that the UI is simply a user-friendly interface for your ViewModels. I did not want to create a button on a page that has any kind of code-behind to switch pages, and I didn’t like the idea of my navigation being spread out throughout all the ViewModels.

I finally came to realize the solution was simple: I needed a ViewModel for the Application itself, which contained the application state, such as the CurrentPage.

Here is an example that builds on the Simple MVVM Example.

The ViewModel

Usually I name the ViewModel ApplicationViewModel or ShellViewModel, but you can call it whatever you want. It is the startup page of the application, and it is usually the only page or window object in my project.

It usually contains

    List<ViewModelBase> PageViewModels
    ViewModelBase CurrentPage
    ICommand ChangePageCommand

Here is an example ApplicationViewModel that I would use to go with the Simple MVVM Example.


    public class ApplicationViewModel : ObservableObject
    {
        #region Fields

        private ICommand _changePageCommand;

        private IPageViewModel _currentPageViewModel;
        private List<IPageViewModel> _pageViewModels;

        #endregion

        public ApplicationViewModel()
        {
            // Add available pages
            PageViewModels.Add(new HomeViewModel());
            PageViewModels.Add(new ProductsViewModel());

            // Set starting page
            CurrentPageViewModel = PageViewModels[0];
        }

        #region Properties / Commands

        public ICommand ChangePageCommand
        {
            get
            {
                if (_changePageCommand == null)
                {
                    _changePageCommand = new RelayCommand(
                        p => ChangeViewModel((IPageViewModel)p),
                        p => p is IPageViewModel);
                }

                return _changePageCommand;
            }
        }

        public List<IPageViewModel> PageViewModels
        {
            get
            {
                if (_pageViewModels == null)
                    _pageViewModels = new List<IPageViewModel>();

                return _pageViewModels;
            }
        }

        public IPageViewModel CurrentPageViewModel
        {
            get
            {
                return _currentPageViewModel;
            }
            set
            {
                if (_currentPageViewModel != value)
                {
                    _currentPageViewModel = value;
                    OnPropertyChanged("CurrentPageViewModel");
                }
            }
        }

        #endregion

        #region Methods

        private void ChangeViewModel(IPageViewModel viewModel)
        {
            if (!PageViewModels.Contains(viewModel))
                PageViewModels.Add(viewModel);

            CurrentPageViewModel = PageViewModels
                .FirstOrDefault(vm => vm == viewModel);
        }

        #endregion
    }

This won’t compile right away because I’ve made some changes to it. For one, all my PageViewModels now inherit from an IPageViewModel interface so they can have some common properties, such as a Name.

I also created a new HomeViewModel and HomeView since its hard to demonstrate navigation unless you have at least 2 pages. The HomeViewModel is a blank class that inherits from IPageViewModel, and the HomeView is just a blank UserControl.

In addition, I added an s to ProductsViewModel since it really deals with multiple products, not a single one.

An added advantage to having a ViewModel to control the application state is that it can also be used to handle other application-wide objects, such as Current User, or Error Messages.

The View

I also need an ApplicationView for my ApplicationViewModel. It needs to contain some kind of Navigation that shows the list of PageViewModels, and clicking on a PageViewModel should execute the ChangePage command.

It also needs to contain a control to display the CurrentPage property, and I usually use a ContentControl for that. This allows me to use DataTemplates to tell WPF how to draw each IPageViewModel.

<Window x:Class="SimpleMVVMExample.ApplicationView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:SimpleMVVMExample"
        Title="Simple MVVM Example" Height="350" Width="525">

    <Window.Resources>
        <DataTemplate DataType="{x:Type local:HomeViewModel}">
            <local:HomeView />
        </DataTemplate>
        <DataTemplate DataType="{x:Type local:ProductsViewModel}">
            <local:ProductsView />
        </DataTemplate>
    </Window.Resources>

    <DockPanel>
        <Border DockPanel.Dock="Left" BorderBrush="Black" BorderThickness="0,0,1,0">
            <ItemsControl ItemsSource="{Binding PageViewModels}">
                <ItemsControl.ItemTemplate>
                    <DataTemplate>
                        <Button Content="{Binding Name}"
                                Command="{Binding DataContext.ChangePageCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                                CommandParameter="{Binding }"
                                Margin="2,5"/>
                    </DataTemplate>
                </ItemsControl.ItemTemplate>
            </ItemsControl>
        </Border>

        <ContentControl Content="{Binding CurrentPageViewModel}" />
    </DockPanel>
</Window>

In this example, I’m using an ItemsControl to display my PageViewModels. Each item is drawn using a Button, and the Button’s Command property is bound to the ChangePageCommand.

Since the Button’s DataContext is the PageViewModel, I used a RelativeSource binding to find the ChangePageCommand. I know that my Window is the ApplicationView, and it’s DataContext is the ApplicationViewModel, so this binding looks up the VisualTree for the Window tag, and gets bound to Window.DataContext.ChangePageCommand.

Also note that I am putting DataTemplates in Window.Resources to tell WPF how to draw each IPageViewModel. By default, if WPF encounters an object in it’s visual tree that it doesn’t know how to handle, it will draw it using a TextBlock containing the .ToString() method of the object. By defining a DataTemplate, I am telling WPF to use a specific template instead of defaulting to a TextBlock.

If you are continuing from the Simple MVVM Example, I moved the ProductView out of a ResourceDictionary and into a UserControl to make this simpler.

Starting the Example

The last thing to do is change App.xaml to make ApplicationView and ApplicationViewModel our startup, instead of ProductView/ProductViewModel.

public partial class App : Application
{
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);

        ApplicationView app = new ApplicationView();
        ApplicationViewModel context = new ApplicationViewModel();
        app.DataContext = context;
        app.Show();
    }
}

Run the project and you should see something that looks like the images below, which quickly switches the CurrentPage when clicking on the Navigation buttons.

Screenshot of HomeHome

Screenshot of ProductsProducts

Summary

And there you have it. A simple navigation example with MVVM.

You can download the source code for this sample from here.

Once you get more comfortable with WPF, I would recommend looking into using a Messaging System, such as MVVM Light’s Messenger, or Microsoft Prism’s EventAggregator to broadcast ChangePage commands from any ViewModel so you wouldn’t need to find the ApplicationViewModel to execute the ChangePageCommand, however that’s for another day.

<< Back – A Simple MVVM Example
>> Next – Communication between ViewModels


How a VirtualizingStackPanel works

November 5, 2011

A VirtualizingStackPanel is recommended instead of a regular StackPanel when you have a large number of scrollable items.

The reason for this is that a regular scrolling StackPanel will render every single UI element in the list when its loaded, including the ones that are not visible, while a VirtualizingStackPanel will only render the visible UI elements. When you scroll a VirtualizingStackPanel it will re-use the existing elements instead of creating new ones, and simply replaces the DataContext behind them.

For example, if you have an VirtualizingStackPanel with 100,000 items, and only 10 are visible at a time, it will render about 14 items (extra items for a scroll buffer). When you scroll, the DataContext behind those 14 controls gets changed, but the actual controls themselves will never get replaced. In contrast, a regular StackPanel would actually render 100,000 items when it gets loaded, which would dramatically decrease the performance of your application.

To see a VirtualizingStackPanel in action, create one that has a bunch of TextBoxes that are not bound to anything. If you type Text in TextBox #1, and that TextBox.Text is not bound to anything, then the Text will stay in the top TextBox when you scroll the list because the control is getting re-used. If you bind TextBox.Text to a value, then the DataContext will change when you scroll, which will replace the displayed Text.


Simplifying PRISM’s EventAggregator

October 9, 2011

I recently started using PRISM’s EventAggregator for messaging in my WPF applications, however I find the syntax confusing, and hard to remember.

Here’s the default syntax for PRISM’s EventAggregator

// Optional: Create Event "Message"
// Needed for multiple parameters, but not for single parameter
// messages. I prefer using one in most cases because I find
// it makes it easier to read the code
public class TickerSymbolSelectedMessage
{
    public string StockSymbol { get; set; }
}

// Create an Event
public class TickerSymbolSelectedEvent : 
    CompositePresentationEvent<TickerSymbolSelectedMessage>{}

// Subscribe to an Event
eventAggregator.GetEvent<ChangeStockEvent>().Subscribe(ShowNews);

public void ShowNews(TickerSymbolSelectedMessage msg)
{
   // Handle Event
}

// Broadcast an Event
eventAggregator.GetEvent<ChangeStockEvent>().Publish(
    new TickerSymbolSelectedMessage{ StockSymbol = “STOCK0” });

There are a few things that irritate me about this syntax:

  • Needing to call GetEvent() all the time before subscribing/publishing
  • Needing a reference to the EventAggregator anywhere I want to use it
  • Needing to create two classes for an Event: the Event itself and the EventMessage (technically this one is optional if you only have one Parameter, but I like to create it anyways because I find it easier to read)

A large portion of the time I am working small apps which usually have a single purpose, so I wrote myself a simple helper class that gets rid of these annoyances. I’m not sure I’d recommend using this in larger apps since it passes all the events over the same channel, but I find it makes my life with small apps much simpler.

Now I just create the EventMessage, and can use some easy Subscribe/Publish calls anywhere in the application. Simple, easy to remember syntax, no need to pass around an EventAggregator object, and all I have to create is my Event Messages.

// Create the Event Message
public class TickerSymbolSelectedMessage
{
    public string StockSymbol { get; set; }
}

// Subscribe to Events
EventSystem.Subscribe<TickerSymbolSelectedMessage>(ShowNews);

public void ShowNews(TickerSymbolSelectedMessage msg)
{
   // Handle Event
}

// Broadcast Events
EventSystem.Publish<TickerSymbolSelectedMessage>(
    new TickerSymbolSelectedMessage{ StockSymbol = “STOCK0”});

And here’s the EventSystem class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Prism.Events;

namespace MyNamespace
{
    /// <summary>
    /// Static EventAggregator
    /// </summary>
    public static class EventSystem
    {
        private static IEventAggregator _current;
        public static IEventAggregator Current
        {
            get
            {
                return _current ?? (_current = new EventAggregator());
            }
        }

        private static CompositePresentationEvent<TEvent> GetEvent<TEvent>()
        {
            return Current.GetEvent<CompositePresentationEvent<TEvent>>();
        }

        public static void Publish<TEvent>()
        {
            Publish<TEvent>(default(TEvent));
        }

        public static void Publish<TEvent>(TEvent @event)
        {
            GetEvent<TEvent>().Publish(@event);
        }

        public static SubscriptionToken Subscribe<TEvent>(Action action, ThreadOption threadOption = ThreadOption.PublisherThread, bool keepSubscriberReferenceAlive = false)
        {
            return Subscribe<TEvent>(e => action(), threadOption, keepSubscriberReferenceAlive);
        }

        public static SubscriptionToken Subscribe<TEvent>(Action<TEvent> action, ThreadOption threadOption = ThreadOption.PublisherThread, bool keepSubscriberReferenceAlive = false, Predicate<TEvent> filter = null)
        {
            return GetEvent<TEvent>().Subscribe(action, threadOption, keepSubscriberReferenceAlive, filter);
        }

        public static void Unsubscribe<TEvent>(SubscriptionToken token)
        {
            GetEvent<TEvent>().Unsubscribe(token);
        }        public static void Unsubscribe<TEvent>(Action<TEvent> subscriber)
        {
            GetEvent<TEvent>().Unsubscribe(subscriber);
        }
    }
}

WPF ItemsControl Example

September 17, 2011

I recently wanted to lookup some ItemsControl examples, and was was quite surprised that my good friend Google was unable to find me any good sites.

So here’s some quick examples using an ItemsControl.

Basic ItemsControl

The basic ItemsControl syntax will look like this:

<ItemsControl ItemsSource="{Binding MyCollection}" />

By default, this will create a Vertical StackPanel, then it will loop through each item in MyCollection, add it to a TextBlock, then add that TextBox to the StackPanel.

Here’s a screenshot of the UI objects that get created, identified with Snoop

The ItemTemplate

Quite often you don’t want to simply display an item as a TextBlock, and that’s where the ItemTemplate comes in.

<ItemsControl ItemsSource="{Binding MyCollection}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding }" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

In this example, I simply changed the TextBlock to a Button, so now when it draws the StackPanel it will draw each item using a Button instead of a TextBlock.

A button is a simple example, however your DataTemplates can be (and frequently are) far more complex than a single element.

The ItemsPanelTemplate

Now suppose you want to display your items in something other than a Vertical StackPanel. That’s where the ItemsPanelTemplate comes in.

<ItemsControl ItemsSource="{Binding MyCollection}">
    <!-- ItemsPanelTemplate -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <UniformGrid Columns="2" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <!-- ItemTemplate -->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding }" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

In this case, I’ve replaced our StackPanel with a UniformGrid that has 2 Columns

The ItemContainerStyle

The ItemContainerStyle can be used to modify the style of all items in the ItemsControl, however it does not apply this style to the ItemTemplate item, but rather the ContentPresenter that wraps each item (See Snoop Screenshot above)

For example, if I had used a Grid instead of a UniformGrid, and added a Grid.Row and Grid.Column bindings to my Button, you would find that the items do not show up in the correct Grid cell. If I wanted to set each item in the correct Grid cell, I would need to use the ItemContainerStyle to style the ContentPresenter that wraps each item.

<ItemsControl ItemsSource="{Binding MyCollection}">
    <!-- ItemsPanelTemplate -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
            </Grid>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>

    <!-- ItemContainerStyle -->
    <ItemsControl.ItemContainerStyle>
        <Style>
            <Setter Property="Grid.Column" 
                    Value="{Binding ColumnIndex}" />
            <Setter Property="Grid.Row" 
                    Value="{Binding RowIndex}" />
        </Style>
    </ItemsControl.ItemContainerStyle>

    <!-- ItemTemplate -->
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Button Content="{Binding Name}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

Note: For all the screenshots above I was binding to an ObservableCollection of strings, however for the last one I created a custom class that had 3 properties: Name, ColumnIndex, and RowIndex


Navigation with MVVM

July 17, 2011

NOTE: I have re-written this article here to provide a better example, and some code samples.


When I first started out with MVVM, I was lost about how you should navigate between pages. I’m a firm believer in using ViewModels to do everything (unless it’s View-specific code), and that the UI is simply a user-friendly interface for your ViewModels. I did not want to create a button on a page that has any kind of code-behind to switch pages, and I didn’t like the idea of my navigation being spread out throughout all the ViewModels.

I finally came to realize the solution was simple: I needed a ViewModel for the Application itself, which contained the application state, such as the CurrentPage.

The ViewModel

Usually I name the ViewModel ShellViewModel or AppViewModel, but you can call it whatever you want. It is the startup page or window in the application, and is usually the only page/window object in my project.

It looks something like this:

    public class ShellViewModel : INotifyPropertyChanged
    {
        private ICommand _changeViewModelCommand;

        private object _currentViewModel;
        private List<object> _viewModels = new List<object>();

        public ShellViewModel()
        {
            ViewModels.Add(new HomeViewModel());
            CurrentViewModel = ViewModels[0];
        }

        private void ChangeViewModel(object viewModel)
        {
            if (!ViewModels.Contains(viewModel))
                ViewModels.Add(viewModel);

            CurrentViewModel = ViewModels.FirstOrDefault(vm => vm == viewModel);
        }
    }

I have omitted the public property implementation and the INotifyPropertyChanged interface methods for sake of readability. The public properties are your standard get/set properties that raise a PropertyChange notification, and the public ChangeViewModelCommand points to the ChangeViewModel method.

The View

I also need a ShellView for my ShellViewModel, so this is what it usually looks like:

<Grid Margin="20">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>

        <!-- Header -->
        <TextBlock Text="Application Name" FontWeight="Bold" FontSize="24" />

        <Line Grid.Row="1" Stroke="Black" Margin="0,5" StrokeThickness="1" Stretch="Fill" X2="1" />        <!-- Content -->
        <ContentControl Grid.Row="2" Content="{Binding CurrentViewModel}"/>
</Grid>

It contains a standard frame for the application, in this case the application name with a horizontal line under it, followed by the CurrentPage in a ContentControl. When a page is displayed in the ContentControl, WPF will lookup the appropriate DataTemplate to use to display that ViewModel (page).

Changing Pages

The ChangePage command can either be called directly through the XAML using something like this:

<Button Command="{Binding RelativeSource={RelativeSource
            AncestorType={x:Type Window}},
            Path=DataContext.ChangeViewModelCommand}
        CommandParameter="{Binding EditCustomerViewModel}"
        />

or you can use an Event system such as PRISM’s EventAggregator or MVVM Light’s Messenger, and the ViewModels would raise a ChangePage event. I prefer to use an Event system personally, but use whatever works for you.

For more on switching between Pages/Views, see this article


Communication between ViewModels with MVVM

June 5, 2011

Communication between ViewModels can be tricky at first glance, but there are some easy frameworks and patterns that can help you out.

For example, lets say you had a ShellViewModel that controlled your entire application, and it has an Exit command. Now lets say one of the sub-view-models in the application would like to call this exit command.

The easiest way is through a Relative Binding to the Window’s DataContext.ExitCommand.

<Button Command="{Binding 
    RelativeSource={RelativeSource AncestorType={x:Type Window},
    Path=DataContext.ExitCommand}}

Of course, this only works well if you can find the control containing the command you want through a binding.

Enter the Event System

Another way is through a loosely coupled event system. I would recommend either MVVM Light’s Messenger or Microsoft Prism’s EventAggregator. You could always build your own event system as well if you really wanted to.

Both event systems makes me think of a paging system. Any ViewModel can broadcast a message, and any ViewModel can subscribe to receive broadcasted messages. Messages are often packaged into different types, so a ViewModel can subscribe to only listen for specific message types such as CloseApplicationMessages.

This kind of loosely coupled event system is ideal for MVVM because the ViewModels don’t need to know about each other to be able to do their job.

Using either of these systems, your ViewModel that handles the event would subscribe to receive a specific message type. It would tell the event system that if a message of type X is broadcasted, send it to a specified delegate method. The ViewModel that wishes to raise the event simply has to broadcast the message and include any parameters needed in the body of the message.

Example using Prism’s EventAggregator

// Subscribe
eventAggregator.GetEvent<CloseAppliactionMessage>().Subscribe(ExitMethod);

// Broadcast
eventAggregator.GetEvent<CloseAppliactionMessage>().Publish();

(I also have some code posted here which simplifies PRISM’s EventAggregator for smaller applications)

Example using MVVM Light’s Messenger

//Subscribe
Messenger.Default.Register<CloseAppliactionMessage>(ExitMethod);

// Broadcast
Messenger.Default.Send<CloseAppliactionMessage>()

A Simple MVVM Example

May 8, 2011

In my opinion, if you are using WPF or Silverlight you should be using the MVVM design pattern. It is perfectly suited to the technology and allows you to keep your code clean and easy to maintain.

The problem is, there are a lot of online resources for MVVM, each with their own way of implementing the design pattern and it can be overwhelming. I would like to present MVVM in the simplest way possible using just the basics.

So lets start at the beginning.

MVVM

MVVM is short for Model-View-ViewModel.

Models are simple class objects that hold data. They should only contain properties and property validation. They are not responsible for getting data, saving data, click events, complex calculations, business rules, or any of that stuff.

Views are the UI used to display data. In most cases, they can be DataTemplates which is simply a template that tells the application how to display a class. It is OK to put code behind your view IF that code is related to the View only, such as setting focus or running animations.

ViewModels are where the magic happens. This is where the majority of your code-behind goes: data access, click events, complex calculations, business rules validation, etc. They are typically built to reflect a View. For example, if a View contains a ListBox of objects, a Selected object, and a Save button, the ViewModel will have an ObservableCollection ObectList, Model SelectedObject, and ICommand SaveCommand.

MVVM Example

I’ve put together a small sample showing these 3 layers and how they relate to each other. You’ll notice that other than property/method names, none of the objects need to know anything about the others. Once the interfaces have been designed, each layer can be built completely independent of the others.

Sample Model

For this example I’ve used a Product Model. You’ll notice that the only thing this class contains is properties and change notification code.

Usually I would also implement IDataErrorInfo here for property validation, however I have left this out for now.

    public class ProductModel : ObservableObject
    {
        #region Fields

        private int _productId;
        private string _productName;
        private decimal _unitPrice;

        #endregion // Fields

        #region Properties

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

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

        public decimal UnitPrice
        {
            get { return _unitPrice; }
            set
            {
                if (value != _unitPrice)
                {
                    _unitPrice = value;
                    OnPropertyChanged("UnitPrice");
                }
            }
        }

        #endregion // Properties
    }

The class inherits from ObservableObject, which is a custom class I use to avoid having to rewrite the property change notification code repeatedly. I would actually recommend looking into Microsoft PRISM’s NotificationObject  or MVVM Light’s ViewModelBase which does the same thing once you are comfortable with MVVM, but for now I wanted to keep 3rd party libraries out of this and to show the code.

    public abstract class ObservableObject : INotifyPropertyChanged
    {
        #region INotifyPropertyChanged Members

        /// <summary>
        /// Raised when a property on this object has a new value.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// Raises this object's PropertyChanged event.
        /// </summary>
        /// <param name="propertyName">The property that has a new value.</param>
        protected virtual void OnPropertyChanged(string propertyName)
        {
            this.VerifyPropertyName(propertyName);

            if (this.PropertyChanged != null)
            {
                var e = new PropertyChangedEventArgs(propertyName);
                this.PropertyChanged(this, e);
            }
        }

        #endregion // INotifyPropertyChanged Members

        #region Debugging Aides

        /// <summary>
        /// Warns the developer if this object does not have
        /// a public property with the specified name. This
        /// method does not exist in a Release build.
        /// </summary>
        [Conditional("DEBUG")]
        [DebuggerStepThrough]
        public virtual void VerifyPropertyName(string propertyName)
        {
            // Verify that the property name matches a real,
            // public, instance property on this object.
            if (TypeDescriptor.GetProperties(this)[propertyName] == null)
            {
                string msg = "Invalid property name: " + propertyName;

                if (this.ThrowOnInvalidPropertyName)
                    throw new Exception(msg);
                else
                    Debug.Fail(msg);
            }
        }

        /// <summary>
        /// Returns whether an exception is thrown, or if a Debug.Fail() is used
        /// when an invalid property name is passed to the VerifyPropertyName method.
        /// The default value is false, but subclasses used by unit tests might
        /// override this property's getter to return true.
        /// </summary>
        protected virtual bool ThrowOnInvalidPropertyName { get; private set; }

        #endregion // Debugging Aides
    }

In addition to the INotifyPropertyChanged methods, there is also a debug method to validate the PropertyName. This is because the PropertyChange notification gets passed in as a String, and I have caught myself forgetting to change this string when I change the name of a Property.

NoteThe PropertyChanged notification exists to alert the View that a value has changed so it knows to update. I have seen suggestions to drop it from the Model and to expose the Model’s properties to the View from the ViewModel instead of the Model, however I find in most cases this complicates things and requires extra coding. Exposing the Model to the View via the ViewModel is much simpler, although either method is valid.

Sample ViewModel

I am doing the ViewModel next because I need it before I can create the View. This should contain everything the User would need to interact with the page. Right now it contains 4 properties: a ProductModel, a GetProduct command, a SaveProduct command, an a ProductId used for looking up a product.

    public class ProductViewModel : ObservableObject
    {
        #region Fields

        private int _productId;
        private ProductModel _currentProduct;
        private ICommand _getProductCommand;
        private ICommand _saveProductCommand;

        #endregion

        #region Public Properties/Commands

        public ProductModel CurrentProduct
        {
            get { return _currentProduct; }
            set
            {
                if (value != _currentProduct)
                {
                    _currentProduct = value;
                    OnPropertyChanged("CurrentProduct");
                }
            }
        }

        public ICommand SaveProductCommand
        {
            get
            {
                if (_saveProductCommand == null)
                {
                    _saveProductCommand = new RelayCommand(
                        param => SaveProduct(),
                        param => (CurrentProduct != null)
                    );
                }
                return _saveProductCommand;
            }
        }

        public ICommand GetProductCommand
        {
            get
            {
                if (_getProductCommand == null)
                {
                    _getProductCommand = new RelayCommand(
                        param => GetProduct(),
                        param => ProductId > 0
                    );
                }
                return _getProductCommand;
            }
        }

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

        #endregion

        #region Private Helpers

        private void GetProduct()
        {
            // You should get the product from the database
            // but for now we'll just return a new object
            ProductModel p = new ProductModel();
            p.ProductId = ProductId;
            p.ProductName = "Test Product";
            p.UnitPrice = 10.00;
            CurrentProduct = p;
        }

        private void SaveProduct()
        {
            // You would implement your Product save here
        }

        #endregion
    }

There is another new class here: the RelayCommand. This is essential for MVVM to work. It is a command that is meant to be executed by other classes to run code in this class by invoking delegates. Once again, I’d recommend checking out the MVVM Light Toolkit’s version of this command when you are more comfortable with MVVM, but I wanted to keep this simple so have included this code here.

    /// <summary>
    /// A command whose sole purpose is to relay its functionality to other
    /// objects by invoking delegates. The default return value for the
    /// CanExecute method is 'true'.
    /// </summary>
    public class RelayCommand : ICommand
    {
        #region Fields

        readonly Action<object> _execute;
        readonly Predicate<object> _canExecute;

        #endregion // Fields

        #region Constructors

        /// <summary>
        /// Creates a new command that can always execute.
        /// </summary>
        /// <param name="execute">The execution logic.</param>
        public RelayCommand(Action<object> execute)
            : this(execute, null)
        {
        }

        /// <summary>
        /// Creates a new command.
        /// </summary>
        /// <param name="execute">The execution logic.</param>
        /// <param name="canExecute">The execution status logic.</param>
        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("execute");

            _execute = execute;
            _canExecute = canExecute;
        }

        #endregion // Constructors

        #region ICommand Members

        [DebuggerStepThrough]
        public bool CanExecute(object parameters)
        {
            return _canExecute == null ? true : _canExecute(parameters);
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameters)
        {
            _execute(parameters);
        }

        #endregion // ICommand Members
    }

Sample View

And now the Views. These are DataTemplates which define how a class should be displayed to the User. There are many ways to add these templates to your application, but the simplest way is to just add them to the startup window’s Resources.

<Window.Resources>
    <DataTemplate DataType="{x:Type local:ProductModel}">
        <Border BorderBrush="Black" BorderThickness="1" Padding="20">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition />
                    <RowDefinition />
                    <RowDefinition />
                </Grid.RowDefinitions>

                <TextBlock Grid.Column="0" Grid.Row="0"  Text="ID" VerticalAlignment="Center" />
                <TextBox Grid.Row="0" Grid.Column="1"  Text="{Binding ProductId}" />

                <TextBlock Grid.Column="0" Grid.Row="1"  Text="Name" VerticalAlignment="Center" />
                <TextBox Grid.Row="1" Grid.Column="1"  Text="{Binding ProductName}" />

                <TextBlock Grid.Column="0" Grid.Row="2"  Text="Unit Price" VerticalAlignment="Center" />
                <TextBox Grid.Row="2" Grid.Column="1"  Text="{Binding UnitPrice}" />

            </Grid>
        </Border>
    </DataTemplate>

    <DataTemplate DataType="{x:Type local:ProductViewModel}">
        <DockPanel Margin="20">
            <DockPanel DockPanel.Dock="Top">
                <TextBlock Margin="10,2" DockPanel.Dock="Left" Text="Enter Product Id" VerticalAlignment="Center" />

                <TextBox Margin="10,2" Width="50" VerticalAlignment="Center" Text="{Binding Path=ProductId, UpdateSourceTrigger=PropertyChanged}" />

                <Button Content="Save Product" DockPanel.Dock="Right" Margin="10,2" VerticalAlignment="Center"
                        Command="{Binding Path=SaveProductCommand}" Width="100" />

                <Button Content="Get Product" DockPanel.Dock="Right" Margin="10,2" VerticalAlignment="Center"
                        Command="{Binding Path=GetProductCommand}" IsDefault="True" Width="100" />
            </DockPanel>

            <ContentControl Margin="20,10" Content="{Binding Path=CurrentProduct}" />
        </DockPanel>
    </DataTemplate>
</Window.Resources>

The View defines two DataTemplates: one for the ProductModel, and one for the ProductViewModel. You’ll need to add a namespace reference  to the Window definition pointing to your Views/ViewModels so you can define the DataTypes. Each DataTemplate only binds to properties belonging to the class it is made for.

In the ViewModel template, there is a ContentControl that is bound to ProductViewModel.CurrentProduct. When this control tries to display the CurrentProduct, it will use the ProductModel DataTemplate.

Starting the Sample

And finally, to start the application add the following on startup:

MainWindow app = new MainWindow();
ProductViewModel viewModel = new ProductViewModel();
app.DataContext = viewModel;
app.Show();

This is found in the code behind the startup file – usually App.xaml.cs.

This creates your Window (the one with the DataTemplates defined in Window.Resources), creates a ViewModel, and it sets the Window’s DataContext to the ViewModel.

And there you have it. A basic look at MVVM.

UPDATE
Sample code can be found here.

Notes

There are many other ways to do the things shown here, but I wanted to give you a good starting point before you start diving into the confusing world of MVVM.

The important thing to remember about using MVVM is your Forms, Pages, Buttons, TextBoxes, etc (the Views) are NOT your application. Your ViewModels are. The Views are merely a user-friendly way to interact with your ViewModels.

So if you want to change pages, you should not be changing pages in the View, but instead you should be setting something like the AppViewModel.CurrentPage = YourPageViewModel. If you want to run a Save method, you don’t put that behind a button’s Click event, but rather bind the Button.Command to a ViewModel’s ICommand property.

I started with  Josh Smith’s article on MVVM, which was a good read but for a beginner like me, some of these concepts flew right over my head.

I’ve never done a blog or tutorial before, but I noticed there is a lot of confusion about what MVVM is and how to use it. Since I struggled through the maze of material online to figure out what MVVM is and how its used, I thought I’d try and write a simpler explanation. I hope this clarifies things a bit and doesn’t make it worse 🙂

>> Next – Navigation with MVVM