An introduction to MVVM pattern using WPF July 17, 2011
Posted by fofo in C#, c# 4.0, Visual Studio 2010, WPF.Tags: MVVM, Patterns, WPF
trackback
In this post I will show you how to build a simple WPF Application using the popular and well know MVVM (Model View View Model) pattern.
I assume that you know the basics of XAML,WPF. I am going to use a hands-one example using Visual Studio and 2010.
Before we go on and begin with our example I must say a few things about MVVM.Make a note that we can use this pattern when building Silverlight applications as well.
So what is MVVM? In a nutshell it is a UI Design Pattern. You do not have to explore too many things or spend too much time studying this pattern before start using it.
A pattern is a documented solution to a specific software problem. So MVVM being a pattern, is a set of guidelines that makes it much easier to write WPF applications.
It is based on a very important software principle called seperation of concerns.By building WPF applications using MVMV we have solid maintainable code.
By breaking apart our application, enables us to do UI testing.
On top of that we have applications that ( that are built with MVVM ) are much more maintenable and extensible. We keep the designers and the developers happy!!!! Each of them can focus on their tasks and noone interferes with each other’s work.
Let’s have a closer look on the main components of MVVM pattern. Have a look at the picture below.It gives a high level overview of the pattern.
The Model has no reference to the View or the ViewModel . It does not or care about the existence of the View or the Model.
The Model is that data. It could be an xml file or a data access layer (e.g EF). It could be a custom object(s) representing a part of our domain.
The View does not have a reference to the Model. A View is defined in XAML and should not have any logic in the code-behind. It binds to the ViewModel by only using data binding.
The ViewModel can be thought of as an abstraction of the View. It provides enough information about the Model data points that the View can use for data-binding. It contains Commands the View can use to interact with the Model. The ViewModel has a reference to the Model.
Let’s start with our hands on example.I will create a simple WPF application
1) Launch Visual Studio 2010 (any edition will do). Choose C# as the development language and WPF Application from the available templates.
2) Choose a suitable name for your application. I have named it “WpfMVVM”
3) Add 3 folders in your solution with the names View,Model,ViewModel.
4) I will use a custom object to store the data so I will add a new class to the Model folder. I will name it Footballer.cs ( yes, we will save and display footballer names ). I will add some properties on this class like firstname,lastname,age,height,weight and another little property called SavedTime so I know when the data was last updated. So the first version of the Footballer class follows.
class Footballer { private string _firstname; public string FirstName { get { return _firstname; } set { _firstname = value; } } private string _lastname; public string LastName { get { return _lastname; } set { _lastname = value; } } private int _age; public int Age { get { return _age; } set { _age = value; } } private double _height; public double Height { get { return _height; } set { _height = value; } } private double _weight; public double Weight { get { return _weight; } set { _weight = value; } } private DateTime _SavedTime; public DateTime SavedTime { get { return _SavedTime; } set { _SavedTime = value; } } }
Then I need to notify my UI (View) that some of these properties changed. I do that by implementing the INotifyPropertyChanged interface.
Now the View is notified when there changes in the property values,since when that happens notifications are fired. This allows the View to display any changes that have been made in the object’s underlying properties. The second version of the Footballer class follows
class Footballer: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"); } } private double _height; public double Height { get { return _height; } set { _height = value; OnPropertyChanged("Height"); } } private double _weight; public double Weight { get { return _weight; } set { _weight = value; OnPropertyChanged("Weight"); } } private DateTime _SavedTime; public DateTime SavedTime { get { return _SavedTime; } set { _SavedTime = value; OnPropertyChanged("SavedTime"); } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string property) { if (PropertyChanged !=null) { PropertyChanged(this, new PropertyChangedEventArgs(property)); } } }
If I want to implement data validation logic, the Model class is a good place to do it.In this case I need to implement the IDataErrorInfo interface.In this example I will add some validation for the fields “FirstName”, “Lastname”. These fields cannot be empty.
The third version of the Footballer class follows
class Footballer:INotifyPropertyChanged,IDataErrorInfo { 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"); } } private double _height; public double Height { get { return _height; } set { _height = value; OnPropertyChanged("Height"); } } private double _weight; public double Weight { get { return _weight; } set { _weight = value; OnPropertyChanged("Weight"); } } private DateTime _SavedTime; public DateTime SavedTime { get { return _SavedTime; } set { _SavedTime = value; OnPropertyChanged("SavedTime"); } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string property) { if (PropertyChanged !=null) { PropertyChanged(this, new PropertyChangedEventArgs(property)); } } public string Error { get { return null; } } public string this[string columnName] { get { string theerror = string.Empty; if ((string.IsNullOrEmpty (_firstname))) { theerror = "This field is required"; } else if ((string.IsNullOrEmpty(_lastname))) { theerror = "This field is required"; } return theerror; } } }
We will have to make some changes to the XAML (Set the ValidatesOnDataErrors=True for firstname and lastname elements) for this to work but I will show you later.
Νow let’s move to the ViewModel implementation. This model must have properties that expose instances of the Model objects.
So in this case we must have a property in the ViewModel class that exposes the Footballer class that lives in the Model.
Add a new item to your project, a class file, name it FootballerViewModel.cs
The first thing I need to do in my new class is to implement the INotifyPropertyChanged interface.This is because the View is bound to the ViewModel. INotifyPropertyChanged interface is the way to push data to the View.
The first version of the ViewModel class follows
class FootballerViewModel:INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
Let’s create a property that is an instance of the Model object .The second version of the ViewModelclass follows
class FootballerViewModel:INotifyPropertyChanged { private Footballer _myfootballer; public Footballer MyFootballer { get { return _myfootballer; } set { _myfootballer = value; OnPropertyChanged("MyFootballer"); } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
Now I will use the constructor for the ViewModel class and populate it with some random data.
The third version of the ViewModel follows
class FootballerViewModel:INotifyPropertyChanged { public FootballerViewModel() { LoadFootballers(); } private void LoadFootballers() { MyFootballer = new Footballer() { FirstName = "Steven", LastName = "Gerrard", Age = 31, Weight = 88.6, Height = 1.84 }; } private Footballer _myfootballer; public Footballer MyFootballer { get { return _myfootballer; } set { _myfootballer = value; OnPropertyChanged("MyFootballer"); } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } }
Now, let’s create the View. The View will be purely XAML. It consists of the visual elements like buttons,textboxes. It is not responsible for retrieving data,implement business logic or validation logic.
First things first. Move the MainWindow.xaml file to the View folder.
Go to the App.xaml file and change the StartupUri attribute of the Application element to StartupUri=”View/MainWindow.xaml”
<Window x:Class="WpfMVVM.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" > <Grid> <Grid.RowDefinitions> <RowDefinition Height="46*" /> <RowDefinition Height="46*" /> <RowDefinition Height="46*" /> <RowDefinition Height="46*" /> <RowDefinition Height="46*" /> <RowDefinition Height="46*" /> <RowDefinition Height="46*" /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="121*" /> <ColumnDefinition Width="382*" /> </Grid.ColumnDefinitions> <TextBlock Height="23" HorizontalAlignment="Left" Margin="10,12,0,0" Name="textBlock1" Text="First Name:" VerticalAlignment="Top" Width="82" FontSize="16" /> <TextBox Grid.Column="1" Height="23" HorizontalAlignment="Left" Margin="45,12,0,0" Name="textBox1" VerticalAlignment="Top" Width="266" /> <TextBlock Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="12,8,0,0" Name="textBlock2" Text="Last Name:" VerticalAlignment="Top" Width="82" FontSize="16" /> <TextBlock Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="12,9,0,0" Name="textBlock3" Text="Age:" VerticalAlignment="Top" FontSize="16" /> <TextBlock Grid.Row="3" Height="23" HorizontalAlignment="Left" Margin="10,12,0,0" Name="textBlock4" Text="Height:" VerticalAlignment="Top" FontSize="16" /> <TextBlock Grid.Row="4" Height="23" HorizontalAlignment="Left" Margin="10,9,0,0" Name="textBlock5" Text="Weight:" VerticalAlignment="Top" FontSize="16" /> <TextBox Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="45,9,0,0" Name="textBox2" VerticalAlignment="Top" Width="266" /> <TextBox Grid.Column="1" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="45,9,0,0" Name="textBox3" VerticalAlignment="Top" Width="266" /> <TextBox Grid.Column="1" Grid.Row="3" Height="23" HorizontalAlignment="Left" Margin="45,12,0,0" Name="textBox4" VerticalAlignment="Top" Width="266" /> <TextBox Grid.Column="1" Grid.Row="4" Height="23" HorizontalAlignment="Left" Margin="45,9,0,0" Name="textBox5" VerticalAlignment="Top" Width="266" /> <TextBlock Grid.Row="5" HorizontalAlignment="Left" Margin="12,12,0,13" Name="textBlock6" Text="Time Saved:" FontSize="16" /> <TextBox Grid.Column="1" Grid.Row="5" Height="23" HorizontalAlignment="Left" Margin="45,13,0,0" Name="textBox6" VerticalAlignment="Top" Width="266" /> <Button Content="Update" Grid.Column="1" Grid.Row="6" Height="24" HorizontalAlignment="Left" Margin="92,15,0,0" Name="button1" VerticalAlignment="Top" Width="156" FontSize="16" FontFamily="Garamond" FontWeight="Bold" BorderBrush="#FF407F2E" Foreground="#FFE39223" Background="#FF175D17" /> </Grid> </Window>
Now let’s make the necessary changes on the View so it can bind to the Model through the ViewModel.
We have first to make a reference to theViewModel class/object so I include the following namespace.
xmlns:football="clr-namespace:WpfMVVM.ViewModel"
This is the first step to hook a View to the ViewModel. We tell WPF where our ViewModel lives.
Then I will create the ViewModel as a resource (static resource).
<Window.Resources> <football:FootballerViewModel x:Key="FootballerViewModel" /> </Window.Resources>
Then in the Grid element I make the following change
Grid DataContext="{StaticResource FootballerViewModel}" >
The DataContext property inherits its value to child elements. So you can set the DataContext on a layout container (Grid) and its values are inherited to all child elements. This is very useful in our case where we want to bind to the same data object.
Databinding is typically done in XAML by using the {Binding} markup extension. We have to bind the Text attribute of the TextBox element to the various properties as implemented in the Model through the ViewModel.
<TextBox Grid.Column="1" Height="23" HorizontalAlignment="Left" Margin="45,12,0,0" Name="textBox1" VerticalAlignment="Top" Width="266" Text="{Binding MyFootballer.FirstName ValidatesOnDataErrors=True}" /> <TextBox Grid.Column="1" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="45,9,0,0" Name="textBox2" VerticalAlignment="Top" Width="266" Text="{Binding MyFootballer.LastName, ValidatesOnDataErrors=True}" /> <TextBox Grid.Column="1" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="45,9,0,0" Name="textBox3" VerticalAlignment="Top" Width="266" Text="{Binding MyFootballer.Age}" /> <TextBox Grid.Column="1" Grid.Row="3" Height="23" HorizontalAlignment="Left" Margin="45,12,0,0" Name="textBox4" VerticalAlignment="Top" Width="266" Text="{<strong>Binding MyFootballer.Height</strong>}" /> <TextBox Grid.Column="1" Grid.Row="4" Height="23" HorizontalAlignment="Left" Margin="45,9,0,0" Name="textBox5" VerticalAlignment="Top" Width="266" Text="{Binding MyFootballer.Weight}" /> <TextBox Grid.Column="1" Grid.Row="5" Height="23" HorizontalAlignment="Left" Margin="45,13,0,0" Name="textBox6" VerticalAlignment="Top" Width="266" Text="{Binding MyFootballer.SavedTime}" />
Run your application and see the values from the domain object appearing in the textboxes.
We do have a button in our UI. We need to update data from the UI and bind the new data to the textboxes.
We need to have a different communnication between the View and the ViewModel. In this case we will use Commands.
First we need to update the XAML.
<Button Content="Update" Grid.Column="1" Grid.Row="6" Height="24" HorizontalAlignment="Left" Margin="92,15,0,0" Name="button1" VerticalAlignment="Top" Width="156" FontSize="16" FontFamily="Garamond" FontWeight="Bold" BorderBrush="#FF407F2E" Foreground="#FFE39223" Background="#FF175D17" Command="{Binding SaveFootballerCommand}" />
So I updated the XAML for the button element by adding the Command=”{Binding SaveFootballerCommand}”
Now we must add some more code in our ViewModel.
public class SaveFootballerCommand:ICommand { Action _saveMethod; public bool CanExecute(object parameter) { return true; } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { _saveMethod.Invoke(); } }
I create a new class, SaveFootballerCommand, that has to implement the ICommand interface. Then I define an Action, _saveMethod, which is what is executed when the button is clicked.
The CanExecute tells me if I am allowed to execute the command.Then I create the Execute method and invoke it.
Now we need to create a property in my ViewModel that exposes that command.
private ICommand _SaveFootballerCommand; public ICommand SaveFootballerCommand { get { return _SaveFootballerCommand; } set { _SaveFootballerCommand = value; OnPropertyChanged("SaveFootballerCommand"); } }
Now we need to create an instance of the SaveFootballerCommand.
private void FireCommand() { SaveFootballerCommand = new SaveFootballerCommand(updateFootballer) ; }
I place the inside my constructor the FireCommand() method.
public FootballerViewModel() { FireCommand(); LoadFootballers(); }
The updateFootballer method is going to be invoked when the command is executed.So I must implement it.
private void updateFootballer() { MyFootballer.SavedTime = DateTime.Now; }
Now I need to create a constructor of the SavePersonCommand class that takes a parameter. The code follows
public SaveFootballerCommand(Action updateFootballer) { _saveMethod = updateFootballer; }
The whole code for the ViewModel class follows
public SaveFootballerCommand(Action updateFootballer) { class FootballerViewModel:INotifyPropertyChanged { public FootballerViewModel() { FireCommand(); LoadFootballers(); } private void FireCommand() { SaveFootballerCommand = new SaveFootballerCommand(updateFootballer) ; } private void updateFootballer() { MyFootballer.SavedTime = DateTime.Now; } private void LoadFootballers() { MyFootballer = new Footballer() { FirstName = "Steven", LastName = "Gerrard", Age = 31, Weight = 88.6, Height = 1.84 }; } private Footballer _myfootballer; public Footballer MyFootballer { get { return _myfootballer; } set { _myfootballer = value; OnPropertyChanged("MyFootballer"); } } private ICommand _SaveFootballerCommand; public ICommand SaveFootballerCommand { get { return _SaveFootballerCommand; } set { _SaveFootballerCommand = value; OnPropertyChanged("SaveFootballerCommand"); } } public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } }
Run your application and click the button.Note how the date is updated.
Note that we do not have written a single line of code to the MainWindow.xaml.cs file.
Now that we have a clear understanding of what MVVM is and what the different components are, let’s review again the main concepts.
The ViewModel is responsible for the state and behaviour of the View and it acts like the “middle man” between the View and the Model.
It the middle layer and its main job is to send View information to the Model and Model information to the View.
It has no dependency on the View so we can reuse the ViewModel on different Views or even other platforms.
The ViewModel exposes the Model as properties or commands.
In any case it must implement the INotifyPropertyChanged interface.
The View binds to properties in the ViewModel. It does that by setting the DataContext of a View to an instance of the ViewModel object.
The Model is tha data.Simple as that. The Model’s job is to represent the data and has no knowledge of where or how the data will be presented.
By using this pattern we can have the designers in our company designing the Views with xaml using Visual Studio Designer or Blend. The developers in our company can work with the Model and the ViewModel writing the data access code and businnes logic . We reduce the development time.
This is great pattern because we can make our code more testable and maintainable.
If you want to have a look at the MVVM more closely have a look here.
It would be nice if you could spare some time and have a look at these related patterns with MVVM pattern like MVP,MVC,PM.
Hope it helps!!! Email me if you need the source code.
Great article for those just getting going on MVVM.
One question though, in the view model you expose the Myfootballer model and bind on the view using it’s properties ;Myfootballer.FirstName, Myfootballer.LastName etc.
Is this the preferred method? Or could the view model expose these properties directly as strings and have the view bind to these?
Are there any benefits to either of these approaches?
Thanks, Mark
Hello This is very nice article to start with many thanks
but I have one question why we have implemented INotifyPropertyChanged on viewmodel if I remove this interface from viewmodel then also every thing working fine. May be I am wrong can you please explain
Hi,
I’m new to MVVM. kindly send me the source of this example.
Its very userful for a clear picture on MVVM Usage. could you send me the source code please
Please send me the source code.
Hi ,Excellent article for a beginners like me but implementation of FireCommand didn’t work for me. I followed the example till the end and now am stuck there.Can you please send me the source code?
It is an excellent article. I followed the same steps to do in Win Rt environment and had to add an interface to talk to the VM. Also ViewModel class is not very clear, so I put the code in the following manner:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using FootBaller.Model;
namespace FootBaller.ViewModel
{
public class FootballerViewModel : INotifyPropertyChanged
{
public FootballerViewModel()
{
FireCommand();
LoadFootballers();
}
private Footballer _myfootballer = null;
public Footballer MyFootballer
{
get
{
return _myfootballer;
}
set
{
_myfootballer = value;
OnPropertyChanged(“MyFootballer”);
}
}
private ICommand _SaveFootballerCommand;
public ICommand SaveFootballerCommand
{
get { return _SaveFootballerCommand; }
set
{
_SaveFootballerCommand = value;
OnPropertyChanged(“SaveFootballerCommand”);
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private void LoadFootballers()
{
MyFootballer = new Footballer()
{
FirstName = “Steven”,
LastName = “Gerrard”,
Age = 31,
Weight = 88.6,
Height = 1.84
};
}
private void updateFootballer()
{
MyFootballer.SavedTime = DateTime.Now;
}
private void FireCommand()
{
SaveFootballerCommand = new SaveFootballerCommand (updateFootballer);
}
}
}
To make the SaveFootballerCommand to work from VM, I added a constructor to SaveFootballerCommand class, and following is the code I got working:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace FootBaller.ViewModel
{
public class SaveFootballerCommand : ICommand
{
Action _saveMethod;
public SaveFootballerCommand(Action actM)
{
_saveMethod = actM;
}
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
_saveMethod.Invoke();
}
}
}
It was an easy implementation for command to work, nice work again.
hey, this is a very nice article for the beginners. Can you please send me the source code.
I need a source thanks
Can you please send the source code of this article
Hi, its nice article. Please send me the source code
Hi there, of course this paragraph is truly nice and I have learned lot of things from it
on the topic of blogging. thanks.
Please email me source code
great tutorial, please send me the code, priombiswas@yahoo.com
Awesome article on MVVM. Thank u so much for the explanations. Please do send me the code
Hi,
I’m new to MVVM. kindly send me the source of this example.
it’s very nice article. Please send me the source code.
Thanks
it’s very nice article. Please send me the source code.
Thanks
nice article keep it thanks
kindly sent me the source code
it’s very nice article. Please send me the source code.
Thanks
blackdeath_166@hotmail.com
HI its very good article. Please send me the code.
suraj.srj387@gmail.com
Please send me the source code.
Thanks a lot!
Please send me the source code
I found an interesting one here https://blossomprogramming.blogspot.in/2017/07/introduction-to-mvvm-in-wpf-model-view.html