Geeks With Blogs

News
Michael Crump Microsoft MVP, INETA Community Champion and XAML Advocate.

I created a getting started guide for the MVVM pattern back in June 2010. Since the guide came out, I had several developers ask me when I was going to publish my MVVM example that I had promised. I played around with a way to present this that did not seem like the same old MVVM blog post that everyone has already written. Most of the blog post that I ran across explaining the pattern had lots of complicated diagrams and code snippets that would leave out vital pieces of information. I decided that I would try to use a little humor and create a step-by-step example of building this from scratch using nothing but the built-in .net framework.

This example should be easy enough for a beginner to the pattern to understand.

Btw, if you are still having problems getting this to work then you can download the full source code here.

So from the top Model View ViewModel has several nicknames.

  • MVVM
  • PresentationModel
  • or just the plain ViewModel
  1. It is just an architectural pattern for Silverlight of WPF.
  2. It is designed to allow Designers to focus on the user experience instead of the business logic
  3. It’s been around since 2005, but has just now taken off because of the success of WPF/Silverlight.

What makes this seem so difficult? A quick search of google returns 3 million results. 3 Million results from X number of people all describing this pattern. That's a lot of information from different people with a wide variety of skill level. Maybe you don’t know what the INotifyPropertyChanged event is, maybe you don’t know what a class is. Most of these examples leave you behind. 

image 

The second thing that I believe intimidates people is the complicated diagrams that everyone is using. I understand everyone would like to appear smart, but sometimes it needs to be dumped down (myself included). The bottom line is that our brains are all wired differently. I am going to try my best to explain this and hopefully someone will benefit. So how about this way to explain it?

Model- is simply your data. 

image
 

View – Your XAML.

image  

ViewModel
– Glues your View and Model
together.

image

Even if you don’t understand, stay tuned because it will come together once you see the project. Let’s create our first MVVM project now.

This project assumes you are using Visual Studio 2010 (at least Express Edition). Open Visual Studio and goto File –> New Project and select Silverlight Application. Go ahead and name this project MVVMDemoSilverlight. Also make sure you are targeting the .NET Framework 4.0.

image

You can take the default for the next screen.

image

Now that we have a fresh Silverlight 4 application, I’d like to add in Josh Smith’s RelayCommand class. This class was written by Josh Smith and featured in his article on MSDN.

Josh Smith describes the reason for doing this:

However, creating a nested class that implements ICommand for each command exposed by a ViewModel can bloat the size of the ViewModel class. More code means a greater potential for bugs.

So right click your Silverlight Project and create a new class.

image

Go ahead and name it RelayCommand.

Now paste the following code into the class file. Make sure that you named your project MVVMDemoSilverlight or it will not compile without changing your namespace name. 

using System;
using System.Windows.Input;

namespace MVVMDemoSilverlight
{
    public class RelayCommand : ICommand
    {
        private Action _handler;
        public RelayCommand(Action handler)
        {
            _handler = handler;
        }

        private bool _isEnabled;
        public bool IsEnabled
        {
            get { return _isEnabled; }
            set
            {
                if (value != _isEnabled)
                {
                    _isEnabled = value;
                    if (CanExecuteChanged != null)
                    {
                        CanExecuteChanged(this, EventArgs.Empty);
                    }
                }
            }
        }

        public bool CanExecute(object parameter)
        {
            return IsEnabled;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            _handler();
        }

    }
}
You should have something similar to this after you copied the code over.

image

Let’s go ahead and setup the base for our ViewModel. Typically, we create a new folder in our project called ViewModel and add a class to that.

Right click the project and select New Folder.

image

Name the folder ViewModel. Now, right click that folder –> Select Add then –> New Class and name the class BusinessViewModel.cs. You structure should look like the one presented below.

image

Now, we need to switch to our MainPage.xaml and edit this page. This application is very simple and this is not a recommended approach for an application this simple. The reason that I’m showing you this way is to take out the complexity of a sophisticated UI and show you a brief sample.

Double click on the MainPage.xaml and copy the code below into it. Overwriting everything in the original MainPage.xaml file.

Below is the full XAML for the screen called MainPage.XAML

<UserControl x:Class="MVVMDemoSilverlight.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:ViewModel="clr-namespace:MVVMDemoSilverlight.ViewModel" mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.DataContext>
        <ViewModel:BusinessViewModel/>
    </UserControl.DataContext>
    <Grid x:Name="LayoutRoot" Background="White" Height="100" Width="350">
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <TextBlock Grid.Column="0">First Name</TextBlock>
        <TextBox Grid.Column="1" Text="{Binding FirstName, Mode=TwoWay}" Height="25" TextAlignment="Right"/>
        <TextBlock Grid.Row="1">Last Name</TextBlock>
        <TextBox Grid.Row="1" Grid.Column="1"  Text="{Binding LastName, Mode=TwoWay}" Height="25" TextAlignment="Right"/>
        <Button Grid.Row="2" Grid.Column="1" Margin="0,5,0,0" Content="Click for Full Name" x:Name="btnMessage" Command="{Binding MessageMeCommand}"  />
    </Grid>
</UserControl>

Three parts are interesting in this code.

  1. <UserControl.DataContext>This code is necessary to show the Usercontrol that the DataContext is coming from our ViewModel.
  2. Binding Mode=”TwoWay” This allows us to be able to update the ViewModel with the values the user enters.
  3. The Command inside of Button. Allow us to tie into a property inside the ViewModel. More about this later.

The UI will look like the screen below. It will simply take the First and Last name and append them to a string to present to the user.

image

That is actually everything that we will need to wire up for the MainPage.xaml. As you can see we have no code-behind in our MainPage.xaml.cs

image

Lets go back to the final piece of the puzzle which is the BusinessViewModel. Copy and paste the entire code below into your BusinessViewModel.cs. We will go over the important parts shortly.

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

namespace MVVMDemoSilverlight.ViewModel
{
    public class BusinessViewModel : INotifyPropertyChanged
    {
        //For our First & Last Names
        private string _firstName;
        private string _lastName;

        public string FirstName
        {
            get { return _firstName; }
            set
            {
                _firstName = value;
                OnPropertyChanged("FirstValue"); //Everything should look standard except for this.
            }
        }
        public string LastName
        {
            get { return _lastName; }
            set
            {
                _lastName = value;
                OnPropertyChanged("SecondValue");
            }
        }
     
        //Handles Property Changed
        public event PropertyChangedEventHandler PropertyChanged;

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

        //To tie into our Command on our Button inside the MainPage.xaml
        private readonly ICommand _messageMeCommand;

        public ICommand MessageMeCommand
        {
            get { return _messageMeCommand; }
        }

        public BusinessViewModel()
        {
            _messageMeCommand = new RelayCommand(MessageMe) {IsEnabled = true};
        }

        private void MessageMe()
        {
            MessageBox.Show(FirstName + "," + LastName);
        }

    }
}
Four parts are interesting in this code.
  1. The using System.ComponentModel. This is includes the base classes and interfaces for implementing attributes and type converters. It also includes binding to data sources.
  2. OnPropertyChanged – This is invoked whenever the effective value of any dependency property on the Framework element has been updated.
  3. PropertyChangedEventHandler – Represents the method that will handle the PropertyChanged event raised when a property is changed on a component.
  4. ICommand – Describes command logic. Typically accomplished through a Binding reference to a data source.

If its easier to look at a picture then just look at the following. This will show you how its tied together.

image

That is pretty much it, you can download the full source code here. If I need to clarify something then please add a comment below. My goal is to mainly show you how its done and let you play with the source code to create your own application.

Feel free to follow me on Twitter.

Posted on Friday, September 10, 2010 7:12 AM | Back to top

Copyright © mbcrump | Powered by: GeeksWithBlogs.net