Before starting with the project let me explain WPF, Silverlight, and MVVM for those who are new to those areas.
WPF
- Short form for Windows Presentation Foundation.
- Next generation of Windows applications / Winforms.
- Uses XAML for UI.
- Supports media, documents, and graphics.
Silverlight
- Cross-platform, cross-browser platform for delivering rich, interactive applications.
- Commonly referred to as a rival to Adobe Flash.
- Uses XAML for UI.
- Sub-set of WPF and can be used only in web applications.
Difference between WPF and Silverlight
| S.No | WPF | Silverlight |
| 1 | Targets Desktop. | Targets Browsers. |
| 2 | Has 3D graphics. | Supports rich online media such as streaming audio, and video. |
| 3 | Runs on Windows OS. | Runs on Windows, Mac, and Linux. |
| 4 | Has a full .NET framework. | Limited .NET framework. |
MVVM
In simple words
View knows ViewModel
ViewModel knows Model
But not vice versa
Why MVVM
- Easy to unit test.
- No need to change the model to support changes in View.
- Very minor changes are required in ViewModel to support changes in View.
- Separates UX designer and developer i.e. the development team can focus on creating ViewModel classes, and the design team can focus on making user-friendly Views.
Simple WPF application using MVVM
Here I am just going to get a student name and age from the user and display the details in a GridView as in the figure.
The important areas covered are MVVM, using Relay Command, and IValueConverter.
Creating a Student class
I created a student class with the following properties
Name,
Age,
JoiningDate
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MVVMDemo
{
public class Student
{
public string Name { get; set; }
public int Age { get; set; }
public DateTime JoiningDate { get; set; }
}
}
Creating ViewModelBase and ViewModel class
It's always a good idea to have a ViewModelBase class and inherit all the ViewModels from that. Hence we can reuse the code for implementing INotifyPropertyChanged.
The main purpose of using INotifyPropertyChanged is to get a notification whenever the property value is changed.
I created a ViewModelBase as below.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace MVVMDemo
{
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
I also created a ViewModel class which inherits from ViewModelBase.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Collections.ObjectModel;
namespace MVVMDemo
{
public class ViewModel : ViewModelBase
{
private Student _student;
private ObservableCollection<Student> _students;
private ICommand _SubmitCommand;
public Student Student
{
get
{
return _student;
}
set
{
_student = value;
NotifyPropertyChanged("Student");
}
}
public ObservableCollection<Student> Students
{
get
{
return _students;
}
set
{
_students = value;
NotifyPropertyChanged("Students");
}
}
public ICommand SubmitCommand
{
get
{
if (_SubmitCommand == null)
{
_SubmitCommand = new RelayCommand(param => this.Submit(), null);
}
return _SubmitCommand;
}
}
public ViewModel()
{
Student = new Student();
Students = new ObservableCollection<Student>();
Students.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(Students_CollectionChanged);
}
// Whenever new item is added to the collection, am explicitly calling notify property changed
void Students_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
NotifyPropertyChanged("Students");
}
private void Submit()
{
Student.JoiningDate = DateTime.Today.Date;
Students.Add(Student);
Student = new Student();
}
}
}
RelayCommand
Since we are following the MVVM pattern, instead of having a Button click event in code behind, we are going to use the Command Property of the button. The RelayCommand allows you to inject the command's logic via delegates ed into its constructor. This approach allows for terse, concise command implementation in ViewModel classes. RelayCommand is a simplified variation of the DelegateCommand.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
namespace MVVMDemo
{
public class RelayCommand : ICommand
{
private readonly Action<object> _execute;
private readonly Predicate<object> _canExecute;
public RelayCommand(Action<object> execute) : this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
}
}
View
Now we have to create a view and bind it with ViewModel properties. The code for the view can be found below. I have used a window, Grid, Textbox, Textblock, Button, ListView, and GridView. Many people can wonder why I am using ListView. Since WPF doesn't support GridView directly, I am using a ListView.
<Window x:Class="MVVMDemo.UserRegistrationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:viewmodel="clr-namespace:MVVMDemo"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<viewmodel:ViewModel x:Key="ViewModel"/>
<viewmodel:DatetimeToDateConverter x:Key="MyConverter"/>
</Window.Resources>
<Grid DataContext="{Binding Source={StaticResource ViewModel}}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Name" HorizontalAlignment="Center"/>
<TextBox Grid.Row="0" Grid.Column="1" Width="100" HorizontalAlignment="Center" Text="{Binding Student.Name, Mode=TwoWay}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Age" HorizontalAlignment="Center"/>
<TextBox Grid.Row="1" Grid.Column="1" Width="100" HorizontalAlignment="Center" Text="{Binding Student.Age, Mode=TwoWay}"/>
<Button Content="Submit" Command="{Binding SubmitCommand}" HorizontalAlignment="Right" Grid.Row="2" Grid.Column="0"/>
<ListView ItemsSource="{Binding Students}" Grid.Row="3" Grid.Column="1" Width="200">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" Width="60"/>
<GridViewColumn Header="Age" DisplayMemberBinding="{Binding Age}" Width="60"/>
<GridViewColumn Header="Joining Date" DisplayMemberBinding="{Binding JoiningDate, Converter={StaticResource MyConverter}}" Width="80"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
If you see the above XAML code, you can see I am using Windows resources in my view. In resources, I am adding a reference to my ViewModel and DateTimeToDateConverter.
ValueConverter
We might often get some values from the property but we have to display some other value in the View. Say for example in my project, the Joining date is the date time value but I need to display only the date. I can do this either by String format in binding or else ValueConverter. I just want to go with the latter one, since you can understand ValueConverter also.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.Windows.Data;
namespace MVVMDemo
{
public class DatetimeToDateConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
DateTime date = (DateTime)value;
return date.ToString("MM/d/yyyy");
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return value;
}
}
}
Now you can start debugging the application. I have attached the Source file also.

VIVEK BARKAMPosted Mar 1, 2018, 3:47 AM
Nice Article.......
Vidya FulsoundarPosted Jul 28, 2017, 1:46 AM
Nice Article ......
kannan vPosted Apr 20, 2017, 3:36 AM
What is the use of this event? public event PropertyChangedEventHandler PropertyChanged;
rupesh malviyaPosted Feb 18, 2016, 2:57 PM
Nice Article .....
Soundar RajanPosted Sep 23, 2015, 9:23 AM
Excellant tutorial. kindly update more
mark rmrezPosted Feb 9, 2015, 2:55 AM
Very nice example. could we connect it to a database to make it more exciting?
uzma nisarPosted Jan 26, 2015, 1:57 AM
nyc
Mai IraPosted Jan 12, 2015, 9:17 PM
Thanks!!!
Bijay SalotryPosted May 9, 2014, 8:01 AM
Nice article...ty
simon sebasthianPosted Apr 22, 2014, 10:58 AM
Thanks, Really helped me to undersrand MVVM..
Kumar VejPosted Aug 23, 2013, 4:51 PM
After the command was executed, if i want to open a new window (typical Window.ModalDialog), how can i do that?
Huu VuPosted Jun 4, 2013, 5:43 AM
thanks
Santosh YadavPosted Apr 27, 2013, 1:49 PM
very fine article. Thanks
Sangam DumnePosted Jan 25, 2013, 5:58 AM
nice one ...thnks
MirceaPosted Nov 21, 2012, 4:32 PM
nice example for begining MVVM
gaurav modiPosted Oct 27, 2012, 1:20 PM
Thanks nice code for beginners..
XavierPosted Sep 6, 2012, 11:32 PM
Plagiarism!!! it's a good effort in giving a simplified article of MVVM that Josh Smith gave in the Feb 2009 MSDN magazine (http://msdn.microsoft.com/en-us/magazine/dd419663.aspx), but the least you could do is cite the author you got most of your article from (you even re-use his exact sentences for the relay command)
Yuri BondarenkoPosted May 29, 2012, 8:55 AM
Thanks! Here is another great WPF resource: http://www.codearsenal.net/
Amresh KumarPosted Feb 8, 2012, 11:24 PM
Good to Start...
Sanjoli GuptaPosted Jan 30, 2012, 11:56 PM
really appreciable...:)
Dinesh BeniwalPosted Jan 30, 2012, 11:54 PM
Good start, Welcome to the C# Corner.
Abhi KumarPosted Jan 30, 2012, 11:28 PM
Very useful article. thanks for sharing.
Aaron CronjePosted Jan 30, 2012, 11:23 PM
Good Explanation...
Stephen JohnsonPosted Jan 30, 2012, 11:01 PM
Its a very useful and good article for those who want to learn how to implement MVVM in a WPF application.
Arjun PanwarPosted Jan 30, 2012, 11:53 AM
Thanks,your article is so valuable