Click here to Skip to main content
Click here to Skip to main content

WPF: MVVM (Model View View-Model) Simplified

By , 20 May 2009
 

Introduction

A few months ago, I took the leap from WinForms programming to WPF and quite naturally, I took to it like a duck to water. Well, to be honest I had been developing Silverlight applications since its inception and being that Silverlight is a subset of WPF, it required a low learning curve to catch on. However, the concept of Commanding was a bit different in WPF and I soon began to see how much more powerful Commanding in WPF was compared to Silverlight.

One of the areas in which Commanding is exemplary is in the way in which it complements MVVM. But what is MVVM, and why is it useful? This is the toughest concept (in my opinion) to grasp when it comes to WPF (and Silverlight) programming. Why you ask? Because it is simple and as developers we often like code or concepts that warp our minds, so when we figure it out we can brag to our peers how it only took 2 hours to understand and implement the next BIG thing (no I am not projecting). On a side note, I have found that everyone who blogs about MVVM complicates it by adding too much code which just throws you for a loop. Simplicity is the key to all things complicated. So let’s delve into a little theory and we will finish up with some short-to-the-point code.

Purpose

The purpose of this post is to:

  1. Give a simple and clear definition of Model View View-Model
  2. Provide a clear and simple sample that clearly illustrates MVVM usage

MVVM?

clip_image001.gif

Figure 1.

Just in case you cannot read the text in the image here it is below:

  1. The View holds a reference to the ViewModel. The View basically displays stuff by Binding to entities in the View Model.
  2. The ViewModel exposes Commands, Notifiable Properties, and Observable Collections to the View. The View Binds to these ViewModel entities/members
  3. The Model is your data and/or application objects that move data while applying Application Logic. If you have a Business Layer, then you might not need this.

Above is a simple figure that tells you exactly what MVVM is. In my own words, the ViewModel is the most significant in the entire pattern as it is the glue that sits between the View and the Model and binds both of them together. Now let’s explore some code.

Code

The application you are about to see is very intricate in design and implementation and as such must not be criticized by anyone. Here is an overview of what the application does. It takes your first name, last name and age and displays it to you in a message box. Below is the really complicated class diagram.

ClassDiagram1.png

Figure 2.

Let’s take a look at the PersonModel class which is the only Model in the application:

namespace OliverCode.MVVM.Model 
{ 
    internal class PersonModel : System.ComponentModel.INotifyPropertyChanged 
    { 
        private string firstName; 
        public string FirstName 
        { 
            get { return firstName; } 
            set 
            { 
                firstName = value; 
                OnPropertyChanged("FirstName"); 
            } 
        } 
        private string lastName; 
        public string LastName 
        { 
            get { return lastName; } 
            set 
            { 
                lastName = value; 
                OnPropertyChanged("LastName"); 
            } 
        } 
        private int age; 
        public int Age 
        { 
            get { return age; } 
            set 
            { 
                age = value; 
                OnPropertyChanged("Age"); 
            } 
        } 
#region INotifyPropertyChanged Members 
        public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; 
        private void OnPropertyChanged(string propertyName) 
        { 
            if (PropertyChanged != null) 
                PropertyChanged(this,
                    new System.ComponentModel.PropertyChangedEventArgs(propertyName)); 
        } 
#endregion 
    } 
}

Person class implements the INotifyPropertyChanged interface which enables a WPF element to be immediately notified if any of the properties changed on a Person object.

Moving on… Let’s look at the View which is cleverly named, PersonView (quite creative if I might add).

<UserControl x:Class="OliverCode.MVVM.View.PersonView" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
Height="Auto" Width="Auto" 
xmlns:local="clr-namespace:OliverCode.MVVM.ViewModel"> 
<StackPanel Orientation="Vertical" Margin="4"> 
<!--Here is where the view gets a reference to the ViewModel Declaratively--> 
<StackPanel.DataContext> 
<local:PersonViewModel /> 
</StackPanel.DataContext> 
<StackPanel Orientation="Vertical" DataContext="{Binding Path=Person, Mode=TwoWay}"
    Margin="4"> 
<StackPanel Orientation="Horizontal"> 
<Label Content="First Name:" Margin="0,0,4,0"/> 
<TextBox Width="250" Text="{Binding Path=FirstName}"/> 
</StackPanel> 
<StackPanel Orientation="Horizontal" Margin="0,5,0,0"> 
<Label Content="Last Name:" Margin="0,0,4,0"/> 
<TextBox Width="250" Text="{Binding Path=LastName}"/> 
</StackPanel> 
<StackPanel Orientation="Horizontal" Margin="0,5,0,0"> 
<Label Content="Age:" Margin="35,0,4,0"/> 
<TextBox Width="50" MaxLength="3" Text="{Binding Path=Age}"/> 
</StackPanel> 
</StackPanel> 
<StackPanel> 
<!—The Command is bound to the Property in the PersonViewModel call SavePersonCommand--> 
<Button Content="Save" HorizontalAlignment="Right" Width="80"
   Command="{Binding Path=SavePersonCommand}"/> 
</StackPanel> 
</StackPanel> 
</UserControl>

The key take away from the XAML above is the way the PersonViewModel is attached to the PersonView’s DataContext. (This is the typical means by which the View gets a reference to the ViewModel.) Also pay attention to the Button element whose Command is using the Binding class to attach the SavepersonCommand, which is a property on the ViewModel. Typically, binding to a command is more complicated than this, but because of the WPF MVVM Toolkit 1.0 (which is located here) from the Microsoft Team, developers can now easily Bind to commands. I have included the DelegateCommand class in the project so you don't need to download it directly. There is also a CommandReference class whose purpose is to resolve limitations in WPF when binding data from XAML. (This is not used in the program.)

WPF MVVM Toolkit 1.0 Tidbits

There are several classes in the toolkit but the one you should pay attention to is the DelegateCommand. This class makes it easy to write a function to handle a gesture or command. Gestures can be thought of as any interaction that can initiate a command. I use the DelegateCommand directly in my PersonViewModel like so:

private DelegateCommand savePersonCommand; 
public ICommand SavePersonCommand 
{ 
    get 
    { 
        if(savePersonCommand == null) 
            savePersonCommand = new DelegateCommand(new Action(SaveExecuted), 
                new Func<bool>(SaveCanExecute)); 
        return savePersonCommand; 
    } 
} 
public bool SaveCanExecute() 
{ 
    return Person.Age > 0 && !string.IsNullOrEmpty(Person.FirstName) && 
        !string.IsNullOrEmpty(Person.LastName); 
} 
public void SaveExecuted() 
{ 
    System.Windows.MessageBox.Show(string.Format("Saved: {0} {1} - ({2})",
        Person.FirstName, Person.LastName, Person.Age)); 
}

Here is the entire personViewModel class:

namespace OliverCode.MVVM.ViewModel 
{ 
    internal class PersonViewModel 
    { 
        public PersonModel Person { get; set; } 
        private DelegateCommand savePersonCommand; 
        public ICommand SavePersonCommand 
        { 
            get 
            { 
                if(savePersonCommand == null) 
                    savePersonCommand = new DelegateCommand(new Action(SaveExecuted),
                        new Func<bool>(SaveCanExecute)); 
                return savePersonCommand; 
            } 
        } 
        public PersonViewModel() 
        { 
            //This data will load as the default person from the model attached to
            //the view 
            Person = new PersonModel 
			{ FirstName = "John", LastName = "Doe", Age = 999 }; 
        } 
        public bool SaveCanExecute() 
        { 
            return Person.Age > 0 && !string.IsNullOrEmpty(Person.FirstName) && 
                !string.IsNullOrEmpty(Person.LastName); 
        } 
        public void SaveExecuted() 
        { 
            System.Windows.MessageBox.Show(string.Format("Saved: {0} {1} - ({2})", 
                Person.FirstName, Person.LastName, Person.Age)); 
        } 
    } 
}

Simple, isn't it? I hope I have helped someone by saving them hours trying to find a simple demonstration of MVVM in WPF. Don't forget to check out http://olivercode.wordpress.com/.

Thank you and happy coding.

History

  • 20th May, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Alphakoda
Software Developer (Senior) 4CoreDev
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionNice article, but this line....memberJerry H.13 Mar '13 - 3:34 
"The application you are about to see is very intricate in design and implementation and as such must not be criticized by anyone." had me chuckling a little bit. Smile | :)
GeneralMy vote of 5memberDerek_Ewing7 Sep '12 - 0:21 
Well explained, thank you.
GeneralMy vote of 5memberFarhan Ghumra24 Aug '12 - 2:44 
Excellent
QuestionAwesome ArticlememberEhsan Hafeez16 Jul '12 - 0:45 
This is a very nice effort to describe the MVVM. apperciated!
GeneralMy vote of 5memberakr.18989@gmail.com20 Jun '12 - 23:21 
Nice Article.......
GeneralMy vote of 5memberasakura896 Jun '12 - 4:01 
thanks. very much appreciated. i'm tired searching all over the web to find simple mvvm tuts for absolute beginner.
AnswerTry this site: http://www.codearsenal.net/2012/05/mvvm.htmlmemberMember 471378529 May '12 - 3:33 
Try this site: http://www.codearsenal.net/2012/05/mvvm.html
GeneralMy Vote of 5memberBITA Moin26 Apr '12 - 6:08 
good article is thx
GeneralMy vote of 1memberMember 858314521 Feb '12 - 20:05 
No MVVM Pattern.
QuestionMy Vote Is 4membermakc666 Feb '12 - 23:37 
Hey,
Nice Article But not Exactly MVVM
If you would have moved the implementation of System.ComponentModel.INotifyPropertyChanged
To PersonViewModel than the MVVM pattern would be complete
The person model shouldn't know anything about the view.
AnswerRe: My Vote Is 4memberDranDane13 Sep '12 - 5:13 
I see this everywhere. It's MVVM. Depending on your architecture you can decide where to put System.ComponentModel.INotifyPropertyChanged. What if one of your thread change something in your model ? You need System.ComponentModel.INotifyPropertyChanged in your model to be able to notify the modification on your view.
GeneralRe: My Vote Is 4membermakc6613 Sep '12 - 21:49 
You are absolutely right this is MVVM but for me its still incomplete.
It depends on how you look at the Person model :a domain model which represents the real state content (an object-oriented approach), or the data access layer that represents that content.
In case of PersonModel being domain model, the example should have demonstrated data access layer,and in case of PersonModel being the data access point the INotifyPropertyChanged shouldn't be in it.
QuestionVery Excellent! but can you explain following?memberSunasara Imdadhusen31 Jan '12 - 2:23 
Hi Alphakoda,
 
Really great article for beginner but i have confusion regarding display multiple records of same PersonView. for example right now it is display only one records inside stack panel but i would like to display set of Persons record in same look and feel in Listbox but i could able.
 
I have changed following in your code but didn't success.
 
public List<PersonModel> Person { get; set; }
public PersonViewModel()
        {
            List<PersonModel> Persons = new List<PersonModel>();
            Persons.Add(new PersonModel { FirstName = "Sunasara", LastName = "Imdadhusen", Age = 29 });
            Persons.Add(new PersonModel { FirstName = "Savaliya", LastName = "Manoj", Age = 28 });
            Person = Persons;
        }
i am not able to see any records on the screen.
 
Please help me and your efforts always appreciated!
 
My vote of 5!
 
Thanks in Advanced.
Imdadhusen

sunaSaRa Imdadhusen
+91 99095 44184

GeneralMy vote of 3memberURVISH SUTHAR from Ahmadabad Gujarat, India26 Jan '12 - 21:54 
Good sample for beginner
GeneralMy vote of 5memberSalam633110 Jan '12 - 23:09 
I found this article as a very good one.. for those who are very new to WPF and MVVM....
GeneralMy vote of 5membergolinvauxb16 Nov '11 - 10:22 
The author is right: this is the most simple and easy to understand MVVM sample I have ever read. Thanks.
GeneralMy vote of 5memberNithin Sundar5 Sep '11 - 1:06 
This is probably the best ever newbie's guide to MVVM.
GeneralMy vote of 5memberMember 474865616 Mar '11 - 11:40 
Very easy to understand MVVM, cheers!
GeneralMy vote of 1memberVivek Krishnamurthy12 Mar '11 - 8:13 
Not MVVM.
GeneralRe: My vote of 1memberSalam633110 Jan '12 - 23:13 
Hello Vivek Krishnamurthy,
why not its MVVM??
let me know what is wrong with this?
could you please give me any link to read about MVVM??
 

Thanks and regardz
Salam
GeneralRe: My vote of 1memberVivek Krishnamurthy24 Feb '12 - 20:55 
Why whould you downvote if you want to read more about MVVM.
 
Following articles sould be good to read and learn
WPF Apps With The Model-View-ViewModel Design Pattern[^]
 
Regards,
Vivek
Regards,
Vivek

GeneralMy vote of 5memberJustinYip22 Aug '10 - 23:35 
Nice article!!
GeneralMy vote of 1memberNikolaj Lynge Olsson27 May '10 - 20:18 
Not mvvm - see PersonModel with INotifyPropertyChanged etc :(
GeneralRe: My vote of 1memberrobsammons31 Mar '11 - 2:56 
I agree. Completely wrong
QuestionRevision for Visual Studio 2010 .Net 4.0?memberFresh Mexican Food Fan20 Apr '10 - 4:56 
Alphakoda, do you plan to rewrite or add another article specifically for the new VS2010 / .Net 4 platform ?
 
I'm just starting to learn WPF and Design patterns, and it would be of great help if you can post VS2010 version of this article.
 
Thanks again for this one.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130523.1 | Last Updated 20 May 2009
Article Copyright 2009 by Alphakoda
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid