WPF MVVM Pattern: A Simple Tutorial for Absolute Beginners

After some research I cracked the very basic steps in MVVM pattern, and then trying to write MVVM tutorials for absolute beginners.

As part of learning MVVM pattern I tried to search many sites and blogs and found most of them are explained in a complicated manner. After some research I cracked the very basic steps in MVVM pattern, and then trying to write MVVM tutorials for absolute beginners.
 
I don't think much more time or words spend for explaining various part of MVVM and the relationship  between MVVM and WPF. If you go to the depth of WPF you will realize that MVVM is the best suitable pattern for WPF (You might not understand the difference between these two) .
 
As a formal procedure I am giving a simple diagram and definition for MVVM
 
1.gif 
I start this tutorial with two examples, i.e WpfSimple.csproj and WpfMvvmTest.csproj
 
For the sake of simplicity, the first project (WpfSimple.csproj) avoids the Model object (an example with Model will come later). 
 
In the example WpfSimple, the view contains only a Button and no code behind, but its click event is loosely bound with ViewModel. The bindings between view and ViewModel are simple to construct because a ViewModel object is set as the DataContext of a view. If property values in the ViewModel change, those new values automatically propagate to the view via data binding. When the user clicks a button in the View, a command on the ViewModel executes to perform the requested action. 
 
The View 
 
2.gif
 
The following code snippets are coming from WpfSimple application (available with tutorial)
  1. <Window x:Class="WpfSimple.MainWindow"  
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.         xmlns:local="clr-namespace:WpfSimple"  
  5.         Title="MainWindow" Height="150" Width="370">  
  6.     <Window.DataContext>  
  7.         <local:MainWindowViewModel/>  
  8.     </Window.DataContext>  
  9.         <Grid>  
  10.         <Button Content="Click"  
  11.                 Height="23"  
  12.                 HorizontalAlignment="Left"  
  13.                 Margin="77,45,0,0"  
  14.                 Name="btnClick"  
  15.                 VerticalAlignment="Top"  
  16.                 Width="203"  
  17.                 Command="{Binding ButtonCommand}"  
  18.                 CommandParameter="Hai" />  
  19.     </Grid>  
  20. </Window>  
ViewModel class used here is MainWindowViewModel, which is the object set as the DataContext of a view.
  1. xmlns:local="clr-namespace:WpfSimple"  
  2. ow.DataContext>  
  3. <local:MainWindowViewModel/>  
  4. /Window.DataContext>  
The ViewModel
 
ViewModel  class used over here is  MainWindowViewModel.cs
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Windows.Input;  
  6. using System.Windows;  
  7.   
  8. namespace WpfSimple  
  9. {  
  10.     class MainWindowViewModel  
  11.     {  
  12.         private ICommand m_ButtonCommand;  
  13.         public ICommand ButtonCommand  
  14.         {  
  15.             get  
  16.             {  
  17.                 return m_ButtonCommand;  
  18.             }  
  19.             set  
  20.             {  
  21.                 m_ButtonCommand = value;  
  22.             }  
  23.         }  
  24.         public MainWindowViewModel()  
  25.         {  
  26.             ButtonCommand=new RelayCommand(new Action<object>(ShowMessage));  
  27.         }  
  28.         public void ShowMessage(object obj)  
  29.         {  
  30.             MessageBox.Show(obj.ToString());  
  31.         }  
  32.     }  
  33. }  
You can see an empty code behind file. If you click on the button it will prompt a message box, despite the lack of event handling methods in the views. When the user clicks on buttons, the application reacts and satisfies the user's requests. This works because of bindings that were established on the Command property of Button displayed in the UI. The command object acts as an adapter that makes it easy to consume a ViewModel's functionality from a view declared in XAML.
 
                Command="{Binding ButtonCommand}" 
                CommandParameter="Hai"
 
RelayCommand
 
In this example RelayCommand class is used for implementing ICommad object. I think it's a simple and standard approach. One more common approach is also available by using nested inner class (will  explain later).
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Windows.Input;  
  6.   
  7. namespace WpfSimple  
  8. {  
  9.     class RelayCommand : ICommand  
  10.     {  
  11.         private Action<object> _action;  
  12.         public RelayCommand(Action<object> action)  
  13.         {  
  14.             _action = action;  
  15.         }  
  16.         #region ICommand Members  
  17.         public bool CanExecute(object parameter)  
  18.         {  
  19.             return true;  
  20.         }  
  21.         public event EventHandler CanExecuteChanged;  
  22.         public void Execute(object parameter)  
  23.         {  
  24.             if (parameter != null)  
  25.             {  
  26.                 _action(parameter);  
  27.             }  
  28.             else  
  29.             {  
  30.                 _action("Hello World");  
  31.             }  
  32.         }  
  33.         #endregion  
  34.     }  
  35. }  
Next, I am going to discuss MVVM with an example having the Model object. So I like talk bit about INotifyPropertyChanged Interface
 
INotifyPropertyChanged
 
The INotifyPropertyChanged interface is used to notify clients, typically binding clients, which a property value has changed. The INotifyPropertyChanged interface contains an event called PropertyChanged. Whenever a property on a ViewModel / Model  object has a new value, it can raise the PropertyChanged event to notify the WPF binding system of the new value. Upon receiving that notification, the binding system queries the property, and the bound property on some UI element receives the new value
 
From the example WpfMvvmTest project I am  taking the following code 
  1. public class Product:INotifyPropertyChanged  
  2. {  
  3.     private int m_ID;  
  4.     private string m_Name;  
  5.     private double m_Price;  
  6.     #region INotifyPropertyChanged Members  
  7.     public event PropertyChangedEventHandler PropertyChanged;  
  8.     private void OnPropertyChanged(string propertyName)  
  9.     {  
  10.         if (PropertyChanged != null)  
  11.         {  
  12.             PropertyChanged(thisnew PropertyChangedEventArgs(propertyName));  
  13.         }  
  14.     }  
  15.     #endregion  
  16.   
  17.     public int ID  
  18.     {  
  19.         get  
  20.         {  
  21.             return m_ID;  
  22.         }  
  23.         set  
  24.         {  
  25.             m_ID = value;  
  26.             OnPropertyChanged("ID");  
  27.         }  
  28.     }  
  29.     public string Name  
  30.     {  
  31.         get  
  32.         {  
  33.             return m_Name;  
  34.         }  
  35.         set  
  36.         {  
  37.             m_Name = value;  
  38.             OnPropertyChanged("Name");  
  39.         }  
  40.     }  
  41.     public double Price  
  42.     {  
  43.         get  
  44.         {  
  45.             return m_Price;  
  46.         }  
  47.         set  
  48.         {  
  49.             m_Price = value;  
  50.             OnPropertyChanged("Price");  
  51.         }  
  52.     }  
  53. }  
Another  approach for binding ViewModel object  as datacontext of View
  1. public partial class App : Application  
  2. {  
  3.     protected override void OnStartup(StartupEventArgs e)  
  4.     {  
  5.         base.OnStartup(e);  
  6.         WpfMvvmTest.MainWindow window = new MainWindow();  
  7.         ProductViewModel VM = new ProductViewModel();  
  8.         window.DataContext = VM;  
  9.         window.Show();  
  10.     }  
  11. }  
In the following code snippet used inner class approach for implementing ICommand interface i.e create a private nested class within the ViewModel class, so that the command has access to private members of its containing ViewModel and does not pollute the namespace.
The disadvantage of this approach is that it requires creation of a nested class that implements ICommand for each command exposed by a ViewModel which will increase the size of the ViewModel class.
  1. class ProductViewModel  
  2. {  
  3.     private IList<Product> m_Products;  
  4.     public ProductViewModel()  
  5.     {  
  6.         m_Products = new List<Product>  
  7.         {  
  8.             new Product {ID=1, Name ="Pro1", Price=10},  
  9.             new Product{ID=2, Name="BAse2", Price=12}  
  10.         };  
  11.     }  
  12.     public IList<Product> Products  
  13.     {  
  14.         get  
  15.         {  
  16.             return m_Products;  
  17.         }  
  18.         set  
  19.         {  
  20.             m_Products = value;  
  21.         }  
  22.     }  
  23.     private ICommand mUpdater;  
  24.     public ICommand UpdateCommand  
  25.     {  
  26.         get  
  27.         {  
  28.             if (mUpdater == null)  
  29.                 mUpdater = new Updater();  
  30.             return mUpdater;  
  31.         }  
  32.         set  
  33.         {  
  34.             mUpdater = value;  
  35.         }  
  36.     }  
  37.     private class Updater : ICommand  
  38.     {  
  39.         #region ICommand Members  
  40.         public bool CanExecute(object parameter)  
  41.         {  
  42.             return true;  
  43.         }  
  44.         public event EventHandler CanExecuteChanged;  
  45.         public void Execute(object parameter)  
  46.         {  
  47.         }  
  48.         #endregion  
  49.     }  
  50. }  
From the following view XAML you can understand how to bind a collection of object to the list control.
  1. <Window x:Class="WpfMvvmTest.MainWindow"  
  2.         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"  
  3.         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"  
  4.         Title="MainWindow" Height="350" Width="525">  
  5.     <Grid Height="314">  
  6.         <Grid.RowDefinitions>  
  7.             <RowDefinition Height="Auto"/>  
  8.             <RowDefinition Height="*"/>  
  9.             <RowDefinition Height="Auto"/>  
  10.         </Grid.RowDefinitions>  
  11.         <ListView Name="ListViewEmployeeDetails" Grid.Row="1" Margin="4,109,12,23"  ItemsSource="{Binding Products}"  >  
  12.             <ListView.View>  
  13.                 <GridView x:Name="grdTest">  
  14.                     <GridViewColumn Header="ID" DisplayMemberBinding="{Binding ID}"  Width="100"/>  
  15.                     <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"  Width="100" />  
  16.                     <GridViewColumn Header="Price" DisplayMemberBinding="{Binding Price}" Width="100" />  
  17.                 </GridView>  
  18.             </ListView.View>  
  19.         </ListView>  
  20.         <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,7,0,0" Name="txtID" VerticalAlignment="Top" Width="178" Text="  
  21. Binding ElementName=ListViewEmployeeDetails,Path=SelectedItem.ID}" />  
  22.         <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,35,0,0" Name="txtName" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=ListViewEmployeeDetails,Path=SelectedItem.Name}" />  
  23.         <TextBox Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="80,61,0,0" Name="txtPrice" VerticalAlignment="Top" Width="178" Text="{Binding ElementName=ListViewEmployeeDetails,Path=SelectedItem.Price}" />  
  24.         <Label Content="ID" Grid.Row="1" HorizontalAlignment="Left" Margin="12,12,0,274" Name="label1" />  
  25.         <Label Content="Price" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,59,0,0" Name="label2" VerticalAlignment="Top" />  
  26.         <Label Content="Name" Grid.Row="1" Height="28" HorizontalAlignment="Left" Margin="12,35,0,0" Name="label3" VerticalAlignment="Top" />  
  27.         <Button Content="Update" Grid.Row="1" Height="23" HorizontalAlignment="Left" Margin="310,40,0,0" Name="btnUpdate"  
  28.                 VerticalAlignment="Top" Width="141"  
  29.                 Command="{Binding Path=UpdateCommad}"  
  30.                 />  
  31.     </Grid>  
  32. </Window>  
So...  I hope you can get a small insight about MVVM from this article.