This article describes the basic use and functionality of the MVVM pattern in WPF.
The Model View ViewModel (MVVM) is an architectural pattern used in software
engineering that originated from Microsoft which is specialized in the
Presentation Model design pattern. It is based on the Model-view-controller
pattern (MVC), and is targeted at modern UI development platforms (WPF and
Silverlight) in which there is a UX developer who has different requirements
than a more "traditional" developer. MVVM is a way of creating client
applications that leverages core features of the WPF platform, allows for simple
unit testing of application functionality, and helps developers and designers
work together with less technical difficulties.
VIEW: A View is defined in XAML and should not have any logic in the
code-behind. It binds to the view-model by only using data binding.
MODEL: A Model is responsible for exposing data in a way that is easily consumable
by WPF. It must implement INotifyPropertyChanged and/or INotifyCollectionChanged
as appropriate.
VIEWMODEL: A ViewModel is a model for a view in the application or we can say as
abstraction of the view. It exposes data relevant to the view and exposes the
behaviors for the views, usually with Commands.
Getting Started:
- Creating a WPF Project. Open Visual Studio
2010.
- Go to File => New => Project
- Select Window in installed templates
- Select WPF Application
- Enter the Name and choose the location.
- Click OK
Now create three folders in root application.
Name should be Model,View,ViewModel and now add a new class in Model folder. My
class name is User and add this namespace
using
System.ComponentModel;
User.cs
public
class User :
INotifyPropertyChanged
{
private int
userId;
private string
firstName;
private string
lastName;
private string
city;
private string
state;
private string
country;
public int
UserId
{
get
{
return userId;
}
set
{
userId = value;
OnPropertyChanged("UserId");
}
}
public string
FirstName
{
get
{
return firstName;
}
set
{
firstName = value;
OnPropertyChanged("FirstName");
}
}
public string
LastName
{
get
{
return lastName;
}
set
{
lastName = value;
OnPropertyChanged("LastName");
}
}
public string
City
{
get
{
return city;
}
set
{
city = value;
OnPropertyChanged("City");
}
}
public string
State
{
get
{
return state;
}
set
{
state = value;
OnPropertyChanged("State");
}
}
public string
Country
{
get
{
return country;
}
set
{
country = value;
OnPropertyChanged("Country");
}
}
#region
INotifyPropertyChanged Members
public event
PropertyChangedEventHandler PropertyChanged;
private void
OnPropertyChanged(string propertyName)
{
if (PropertyChanged !=
null)
{
PropertyChanged(this,
new
PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
Now right click on ViewModel folder and add a new class.
UserViewModel.cs
using
System.Windows.Input;
using
System.ComponentModel;
class
UserViewModel
{
private
IList<User> _UsersList;
public UserViewModel()
{
_UsersList = new
List<User>
{
new
User{UserId = 1,FirstName="Raj",LastName="Beniwal",City="Delhi",State="DEL",Country="INDIA"},
new
User{UserId=2,FirstName="Mark",LastName="henry",City="New
York", State="NY", Country="USA"},
new
User{UserId=3,FirstName="Mahesh",LastName="Chand",City="Philadelphia",
State="PHL", Country="USA"},
new
User{UserId=4,FirstName="Vikash",LastName="Nanda",City="Noida",
State="UP", Country="INDIA"},
new
User{UserId=5,FirstName="Harsh",LastName="Kumar",City="Ghaziabad",
State="UP", Country="INDIA"},
new
User{UserId=6,FirstName="Reetesh",LastName="Tomar",City="Mumbai",
State="MP", Country="INDIA"},
new
User{UserId=7,FirstName="Deven",LastName="Verma",City="Palwal", State="HP",
Country="INDIA"},
new
User{UserId=8,FirstName="Ravi",LastName="Taneja",City="Delhi",
State="DEL", Country="INDIA"}
};
}
public IList<User>
Users
{
get {
return _UsersList; }
set { _UsersList =
value; }
}
private ICommand
mUpdater;
public
ICommand UpdateCommand
{
get
{
if (mUpdater ==
null)
mUpdater = new
Updater();
return mUpdater;
}
set
{
mUpdater = value;
}
}
private class
Updater :
ICommand
{
#region
ICommand Members
public bool
CanExecute(object parameter)
{
return
true;
}
public event
EventHandler CanExecuteChanged;
public void
Execute(object parameter)
{
}
#endregion
}
}
Now let's move on View, Add a new windows in View
Folder.
MainPage.xaml
<Window
x:Class="WpfMVVMSample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="485"
Width="525">
<Grid
Margin="0,0,0,20">
<Grid.RowDefinitions>
<RowDefinition
Height="Auto"/>
<RowDefinition
Height="*"/>
<RowDefinition
Height="Auto"/>
</Grid.RowDefinitions>
<ListView
Name="UserGrid"
Grid.Row="1"
Margin="4,178,12,13"
ItemsSource="{Binding
Users}" >
<ListView.View>
<GridView
x:Name="grdTest">
<GridViewColumn
Header="UserId"
DisplayMemberBinding="{Binding
UserId}"
Width="50"/>
<GridViewColumn
Header="First
Name"
DisplayMemberBinding="{Binding
FirstName}"
Width="80" />
<GridViewColumn
Header="Last
Name"
DisplayMemberBinding="{Binding
LastName}"
Width="100"
/>
<GridViewColumn
Header="City"
DisplayMemberBinding="{Binding
City}"
Width="80"
/>
<GridViewColumn
Header="State"
DisplayMemberBinding="{Binding
State}"
Width="80"
/>
<GridViewColumn
Header="Country"
DisplayMemberBinding="{Binding
Country}"
Width="100"
/>
</GridView>
</ListView.View>
</ListView>
<TextBox
Grid.Row="1"
Height="23"
HorizontalAlignment="Left"
Margin="80,7,0,0"
Name="txtUserId"
VerticalAlignment="Top"
Width="178"
Text="{Binding
ElementName=UserGrid,Path=SelectedItem.UserId}"
/>
<TextBox
Grid.Row="1"
Height="23"
HorizontalAlignment="Left"
Margin="80,35,0,0"
Name="txtFirstName"
VerticalAlignment="Top"
Width="178"
Text="{Binding
ElementName=UserGrid,Path=SelectedItem.FirstName}"
/>
<TextBox
Grid.Row="1"
Height="23"
HorizontalAlignment="Left"
Margin="80,62,0,0"
Name="txtLastName"
VerticalAlignment="Top"
Width="178"
Text="{Binding
ElementName=UserGrid,Path=SelectedItem.LastName}"
/>
<Label
Content="UserId"
Grid.Row="1"
HorizontalAlignment="Left"
Margin="12,12,0,274"
Name="label1"
/>
<Label
Content="Last
Name"
Grid.Row="1"
Height="28"
HorizontalAlignment="Left"
Margin="12,60,0,0"
Name="label2"
VerticalAlignment="Top"
/>
<Label
Content="First
Name"
Grid.Row="1"
Height="28"
HorizontalAlignment="Left"
Margin="12,35,0,0"
Name="label3"
VerticalAlignment="Top"
/>
<Button
Content="Update"
Grid.Row="1"
Height="23"
HorizontalAlignment="Left"
Margin="310,40,0,0"
Name="btnUpdate"
VerticalAlignment="Top"
Width="141"
Command="{Binding
Path=UpdateCommad}"
/>
<TextBox
Grid.Row="1"
Height="23"
HorizontalAlignment="Left"
Margin="80,143,0,0"
x:Name="txtCity"
VerticalAlignment="Top"
Width="178"
Text="{Binding
SelectedItem.City,
ElementName=UserGrid}"
/>
<Label
Content="Country"
Grid.Row="1"
Height="28"
HorizontalAlignment="Left"
Margin="12,141,0,0"
x:Name="label2_Copy"
VerticalAlignment="Top"
/>
<TextBox
Grid.Row="1"
Height="23"
HorizontalAlignment="Left"
Margin="80,88,0,0"
x:Name="txtCountry"
VerticalAlignment="Top"
Width="178"
Text="{Binding
SelectedItem.Country,
ElementName=UserGrid}"
/>
<Label
Content="City"
Grid.Row="1"
Height="28"
HorizontalAlignment="Left"
Margin="12,86,0,0"
x:Name="label2_Copy1"
VerticalAlignment="Top"
/>
<TextBox
Grid.Row="1"
Height="23"
HorizontalAlignment="Left"
Margin="80,115,0,0"
x:Name="txtSTate"
VerticalAlignment="Top"
Width="178"
Text="{Binding
SelectedItem.State,
ElementName=UserGrid}"
/>
<Label
Content="State"
Grid.Row="1"
Height="28"
HorizontalAlignment="Left"
Margin="12,113,0,0"
x:Name="label2_Copy2"
VerticalAlignment="Top"
/>
</Grid>
</Window>
App.xaml.cs
Now bind on application startup.
protected
override void
OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
WpfMVVMSample.MainWindow window =
new MainWindow();
UserViewModel VM =
new UserViewModel();
window.DataContext = VM;
window.Show();
}
Run the application to see the result.
Image 1.
Click on row.
Image 2.
You can edit user detail in textboxes and click update button.
Image 3.