Model View ViewModel (MVVM) Introduction: Part 3

As you know, in a MVVM Design Pattern there is no code form Code Behind but if you havn't worked before with MVVM or MVC then if you only understand client/server architecture then you will think that these patterns will not be powerful because there is no click event, but you are wrong. It's more powerful and so simple to a client/server architecture. Here there is no code in the view (XAML code behind). There is also no specific base class for a view or view model, but still it's used a lot . Then what's there on, only notifications and collections of notifications and commands in the view model only, that takes care of everything about the view.

So for this article I'll focus on that, one more important core component of MVVM, Events (property and collection change events) or INotifyPropertyChanged.

The idea behind a property and collection change binding (client code) is to know the source data change. The target of these events quick response as retrieved data and assigns it to the target to keep a quick change of the view. For this, the source must have implemented the INotifyPropertyChanged interface. This interface has one powerfull event, PropertychangedEventHandler. The source object must inherit from a dependency property. If your properties expose some generic list or collection then the source object must be the INotifyCollectionChanged interface, this interface has a collection changed event that will notify you when your items will be added and removed from the collection, but generally we did not use this because the framework itself provides this cool feature class ObsevalbeCollection<T> generic collection type that is very easily exposed to the notification. The over all concept behind the event in the interface is a quick response to a view to view model and vice versa whenever any operation happens in the source then the target is quickly updated.

How the Notification Concept work in the Model View ViewModel

It is better to understand notification first. You should understand DataBinding in MVVM for a better understanding of the importance of "INotifyPropertyChanged" or "INotifyCollectionChanged".

The following image explains this.
Model View ViewModel
In the preceding image I show how to bind ViewModel data to a view. Here I am binding my view to my ViewModel.

TextBlock is a XAML Control. Text is a property of the XAML control and Binding is a dependency Property. Later I'll explore more about Dependency Properties. Here FirstName is a ViewModel object CLR Property. This Binding key will take care of the binding, even he doesn't know the nature of the object.

If you are a beginner in data binding in XAML then I 'll recommend that you first go through the following link that I explore here as databind in XAML:

Data Binding in XAML (WPF, Silverlight, Windows Phone or Win8 App) Part 1
databind in XAML
In XAML any control can bind to a dependency property to any data using the Data binding way. Even the control doesn't need to know about the Data object. The Dependency property has several special features, you can mainly register your control for a change event of the dependency property, so when someone changes the control property then the databind object will be notified and it can update the object .
databind in XAML1
INotifyPropertyChanged does same things a I explained above. The Databinding object from XAML knows about this interface and will query the data object. When it has this interface, the databinding object registers itself for the change. In this way you can get two-way binding. When one side changes and the other side is updated, if you use ObesableCollection<T> for any collection then these can notify any control.

Implementation of INotifyPropertyChanged

Implemetation of the INotifyPropertyCahanged interface is very simple. Start by defining the base class that impements this interfae as I am showing in the following few images.
Implimenataion of INotifyPropertyChanged
In the preceding image I show how to access an INotifyPropertyChanged Interface. In the following I am explaining how implement this interface member and bind our property, step-by-step.
Implimenataion of INotifyPropertyChanged1
One Sample Example of Model View ViewModel

In this series I have already explained XAML Layout, provided and introduction to MVVM, DataBinding and Commands. This article focuses on Notification change in MVVM. If you are a beginner then please go through this article before this.

Various Types of Panels in XAML Layout

MVVM (Model View ViewModel) Introduction: Part 1

Data Binding in XAML (WPF, Silverlight, Windows Phone or Win8 App) Part 1

Model View ViewModel (MVVM) Introduction: Part 2

In this sample of a View I use a ListBox XAML Control and use a datatemplate to display the Author details customized and based on the selection of his Contribution it is showing on the Right-hand side. These all are common XAML control TextBlocks and stack panels. This sample is a Complete Flowing Model View ViewModel Design Pattern, here there is not any code form code behind.
Example of Model View ViewModel
Model

In the Model I am storing all author data, for that I create an Author Class and define a class member property in the Model, like Point, CountryFirstNameArticles,

Blogs, News, Resources, Tutorials, ForumPosts, Downloads, BookChapter, Photos, Videos, InterviewQuestions, About, image and Ranks. In short, Related to the author all information is defined then creating one ObservableCollection<Authors> AuthorsRecords.

And we store all Author information in this ObservableCollection.

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Collections.ObjectModel;  
  4. using System.Linq;  
  5. using System.Text;  
  6. using System.Threading.Tasks;  
  7.   
  8. namespace MVVM_Sample.Model  
  9. {  
  10.     public class Authors  
  11.     {  
  12.  
  13.  
  14.         #region " AuthorsName Property "  
  15.         /// <summary>  
  16.         ///   
  17.         /// </summary>  
  18.         public string Name { getset; }  
  19.         #endregion  
  20.  
  21.         #region " Articles  Property "  
  22.         /// <summary>  
  23.         ///   
  24.         /// </summary>  
  25.         public string Articles { getset; }  
  26.         #endregion  
  27.  
  28.         #region "  Blogs  Property "  
  29.         /// <summary>  
  30.         ///   
  31.         /// </summary>  
  32.         public string Blogs { getset; }  
  33.         #endregion  
  34.  
  35.         #region " News  Property "  
  36.         /// <summary>  
  37.         ///   
  38.         /// </summary>  
  39.         public string News { getset; }  
  40.         #endregion  
  41.         #region " Resources  Property "  
  42.         /// <summary>  
  43.         ///   
  44.         /// </summary>  
  45.         public string Resources { getset; }  
  46.         #endregion  
  47.  
  48.         #region " Tutorials   Property "  
  49.         /// <summary>  
  50.         ///   
  51.         /// </summary>  
  52.         public string Tutorials { getset; }  
  53.         #endregion  
  54.  
  55.         #region " Forum Posts  Property "  
  56.         /// <summary>  
  57.         ///   
  58.         /// </summary>  
  59.         public string ForumPosts { getset; }  
  60.         #endregion  
  61.  
  62.         #region " Downloads   Property "  
  63.         /// <summary>  
  64.         ///   
  65.         /// </summary>  
  66.         public string Downloads { getset; }  
  67.         #endregion  
  68.  
  69.         #region " Book Chapter  Property "  
  70.         /// <summary>  
  71.         ///   
  72.         /// </summary>  
  73.         public string BookChapter { getset; }  
  74.         #endregion  
  75.  
  76.         #region " Photos   Property "  
  77.         /// <summary>  
  78.         ///   
  79.         /// </summary>  
  80.         public string Photos { getset; }  
  81.         #endregion  
  82.  
  83.         #region " Videos   Property "  
  84.         /// <summary>  
  85.         ///   
  86.         /// </summary>  
  87.         public string Videos { getset; }  
  88.         #endregion  
  89.  
  90.         #region " Interview Questions   Property "  
  91.         /// <summary>  
  92.         ///   
  93.         /// </summary>  
  94.         public string InterviewQuestions { getset; }  
  95.         #endregion  
  96.  
  97.         #region " About Authors   Property "  
  98.         /// <summary>  
  99.         ///   
  100.         /// </summary>  
  101.         public string About { getset; }  
  102.         #endregion  
  103.  
  104.         #region " Authors Ranks   Property "  
  105.         /// <summary>  
  106.         ///   
  107.         /// </summary>  
  108.         public string Ranks { getset; }  
  109.         #endregion  
  110.  
  111.         #region " Point   Property "  
  112.         /// <summary>  
  113.         ///   
  114.         /// </summary>  
  115.         public string Point { getset; }  
  116.         #endregion  
  117.  
  118.         #region " Country   Property "  
  119.         /// <summary>  
  120.         ///   
  121.         /// </summary>  
  122.         public string Country { getset; }  
  123.         #endregion  
  124.   
  125.          
  126.   
  127.   
  128.         public string image { getset; }  
  129.         public static ObservableCollection<Authors> GetAuthorsRecord()  
  130.         {  
  131.             ObservableCollection<Authors> AuthorsRecords = new ObservableCollection<Authors>  
  132.             {  
  133.                 new Authors{Point="40960",Country="Philadelphia, United States",Name="Mahesh Chand ",Articles="1237", Blogs="688",News="558",Resources="454",Tutorials="47",ForumPosts="4554",Downloads="11",BookChapter="0",Photos="171",Videos="122",InterviewQuestions="81",  
  134.                     About="Mahesh Chand is founder of C# Corner. C# Corner founded in 1999 is a  
  135. FREE member contributions based open platform for developers to solve problems, learn new technology and hang out. Mahesh has been awarded prestigious Microsoft MVP Award for 8 consecutive years for his contributions to the developer community. Mahesh is also an author of several programming books. Mahesh authored and published his first book A Programmer’s Guide to ADO.NET in C# with APress at the age of 25. Since then, Mahesh went on to author several more .NET programming books.",  
  136.                     image="Image/mahesh.png",Ranks="1"},  
  137.                 new Authors{Point="18063",Country="United Kingdom",Name="Vulpes",Articles="23", Blogs="5",News="14",Resources="0",Tutorials="0",ForumPosts="9494",Downloads="0",BookChapter="0",Photos="0",Videos="0",InterviewQuestions="0",  
  138.                     About="",image="Image/b942f9.gif",Ranks="2"},  
  139.                 new Authors{Point="12215",Country="India",Name="Dinesh Beniwal ",Articles="538", Blogs="132",News="38",Resources="26",Tutorials="0",ForumPosts="226",Downloads="0",BookChapter="0",Photos="0",Videos="0",InterviewQuestions="13",  
  140.                     About="",image="Image/dbeniwal321.jpg",Ranks="3"},  
  141.                 new Authors{Point="11372",Country="India",Name="Rohatash Kumar ",Articles="522", Blogs="66",News="1",Resources="7",Tutorials="0",ForumPosts="202",Downloads="0",BookChapter="0",Photos="0",Videos="0",InterviewQuestions="10",  
  142.                     About="I am a Microsoft .NET software Developer and author and C# Corner MVP. I hold Masters degree in Computer Science and Applications and Bachelor’s degree in Mathematics. His main skills are C#, ASP.Net, MVC,  Jscript, JQuery, WCF, SQL Server.",image="Image/rohatash.jpg",Ranks="4"},  
  143.                 new Authors{Point="11088",Country="India", Name="Dhananjay Kumar",Articles="487", Blogs="34",News="3",Resources="18",Tutorials="18",ForumPosts="51",Downloads="0",BookChapter="0",Photos="0",Videos="21",InterviewQuestions="0",  
  144.                     About="Dhananjay Kumar is a developer who blogs at http://debugmode.net/. He is Microsoft MVP, Telerik MVP and Mindcracker MVP. You can follow him on twitter  @debug_mode.",image="Image/dhananjaycoder.png",Ranks="5"},  
  145.                 new Authors{Point="10964",Country="Bhubaneswar, India",Name="Satyapriya Nayak",Articles="140", Blogs="232",News="0",Resources="0",Tutorials="0",ForumPosts="4631",Downloads="0",BookChapter="0",Photos="0",Videos="0",InterviewQuestions="25",  
  146.                     About="Satyapriya Nayak is a software developer from Bhubaneswar, India. He holds a Bachelor's degree in Electronics and telecommunication and is an active member of C# Corner. ",image="Image/satyapriyanayak.jpg",Ranks="6"},  
  147.                 new Authors{Point="10850",Country="New Jersey, United States",Name="Vijai Anand",Articles="433", Blogs="369",News="0",Resources="0",Tutorials="0",ForumPosts="37",Downloads="0",BookChapter="0",Photos="0",Videos="0",InterviewQuestions="0",  
  148.                     About="Vijai Anand has been working in IT industry for over 4 years. He holds Bachelor's degree in Electronics and Communication Engineering. Vijai write articles and blogs related to SharePoint 2013, SharePoint 2010, Silverlight, SharePoint Workspace, SharePoint Designer 2010, Powershell and C #. He holds Mindcracker MVP (2010, 2011, 2012 & 2013)  and Microsoft MVP (2013) award.",image="Image/anavijai.png",Ranks="7"},  
  149.                 new Authors{Point="10391",Country="Bokaro Steel City, India",Name="Abhimanyu K Vatsa",Articles="433", Blogs="38",News="11",Resources="0",Tutorials="1",ForumPosts="637",Downloads="0",BookChapter="0",Photos="16",Videos="17",InterviewQuestions="0",  
  150.                     About="Microsoft MVP | Author | IT Faculty | Student of M.Tech. IT | Blogs at ITORIAN.COM",image="Image/abhikumarvatsa.jpg",Ranks="8"},  
  151.                 new Authors{Point="8761",Country="Granada Hills, United States",Name="Sam Hobbs",Articles="16", Blogs="0",News="17",Resources="0",Tutorials="0",ForumPosts="6531",Downloads="0",BookChapter="0",Photos="0",Videos="0",InterviewQuestions="0",  
  152.                     About="Programmer / Analyst initially for the Unites States Army in 1972. Subsequent employers and clients have included Carte Blanche, Bank of America, Parsons Corporation, Lockheed Corporation and SHL Systemhouse",image="Image/SamTomato.jpg",Ranks="9"},  
  153.                 new Authors{Point="8512",Country="India",Name="Suthish Nair",Articles="62", Blogs="86",News="37",Resources="0",Tutorials="0",ForumPosts="5427",Downloads="0",BookChapter="0",Photos="34",Videos="",InterviewQuestions="1",  
  154.                     About="",image="Image/suthish_nair.jpg",Ranks="10"},  
  155.             };  
  156.             return AuthorsRecords;  
  157.         }  
  158.     }  
  159. }  

ViewModel

Above I already explained how to implement an INotifyPropertyChanged interface in a ViewModel.

Here the ViewModel is implementing the INotifyPropertyChanged interface and is also defining an ObservableCollection for accessing the records from the Model and display the selected records on the View .

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4.   
  5. using System.Linq;  
  6. using System.Text;  
  7. using System.Threading.Tasks;  
  8. using MVVM_Sample.Model;  
  9. using System.Collections.ObjectModel;  
  10. namespace MVVM_Sample.ViewModel  
  11. {  
  12.     class MainViewModel :INotifyPropertyChanged  
  13.     {  
  14.         private Authors speaker;  
  15.       public  ObservableCollection<Authors> _speaker;  
  16.        public ObservableCollection<Authors> Listofspeaker  
  17.         {  
  18.             get  
  19.             {  
  20.                 return _speaker;  
  21.             }  
  22.             set  
  23.             {  
  24.                 if (_speaker != null)  
  25.                 {  
  26.                     _speaker = value;  
  27.                     PropertyChanged(thisnew PropertyChangedEventArgs("Listofspeaker"));  
  28.                 }  
  29.             }  
  30.         }  
  31.        public Authors SelectedAuthors  
  32.         {  
  33.             get  
  34.             {  
  35.                 return speaker;  
  36.             }  
  37.             set  
  38.             {  
  39.                 speaker = value;  
  40.                 PropertyChanged(thisnew PropertyChangedEventArgs("SelectedAuthors"));  
  41.             }  
  42.         }  
  43.        public MainViewModel()  
  44.         {  
  45.             _speaker = Authors.GetAuthorsRecord();  
  46.         }  
  47.         #region INotifyPropertyChanged Members  
  48.         public event PropertyChangedEventHandler PropertyChanged;  
  49.         #endregion  
  50.     }  
  51. }  
View

Our View is complete. In the XAML Code here I am just setting the DataContext and then binding data from the ViewModel to the View and I am using a listbox for displaying the list of authors and displaying his contribution in a TextBlock.

  1. <Window x:Class="MVVM_Sample.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:MVVM_Sample.ViewModel"  
  5.         Title="MainWindow" Height="350" Width="525" Background="White">  
  6.     <Window.DataContext>  
  7.         <local:MainViewModel></local:MainViewModel>  
  8.     </Window.DataContext>  
  9.     <Grid>  
  10.         <Grid.ColumnDefinitions>  
  11.             <ColumnDefinition Width="1*"></ColumnDefinition>  
  12.             <ColumnDefinition Width="3*"></ColumnDefinition>  
  13.         </Grid.ColumnDefinitions>  
  14.        
  15.         <ListBox  ItemsSource="{Binding Listofspeaker}"  SelectedItem="{Binding SelectedAuthors,Mode=TwoWay}">  
  16.             <ListBox.ItemTemplate>  
  17.                 <DataTemplate>                    
  18.                     <Grid Margin="0,5,0,0">  
  19.                         <Grid.ColumnDefinitions>  
  20.                             <ColumnDefinition Width="auto"></ColumnDefinition>  
  21.                             <ColumnDefinition></ColumnDefinition>  
  22.                         </Grid.ColumnDefinitions>  
  23.                         <Image Source="{Binding image}" Height="80" Width="80" Grid.Column="0"></Image>  
  24.                         <StackPanel Grid.Column="1">  
  25.                             <TextBlock Text="{Binding FirstName}" Margin="5,1,0,1"></TextBlock>  
  26.                             <TextBlock Text="{Binding Country}" Margin="5,1,0,1"></TextBlock>  
  27.                             <StackPanel Orientation="Horizontal">  
  28.                                 <TextBlock Text="Ranks #" Margin="5,1,0,1"></TextBlock>  
  29.                                 <TextBlock Text="{Binding Ranks}" Margin="3,1,0,1"></TextBlock>  
  30.                             </StackPanel>  
  31.                             <StackPanel Orientation="Horizontal">  
  32.                                 <TextBlock Text="Point" Margin="5,1,0,1"></TextBlock>  
  33.                                 <TextBlock Text="{Binding Point}" Margin="3,1,0,1"></TextBlock>  
  34.                             </StackPanel>  
  35.                         </StackPanel>  
  36.                     </Grid>  
  37.                 </DataTemplate>  
  38.             </ListBox.ItemTemplate>  
  39.         </ListBox  >  
  40.         <Grid Grid.Column="1" DataContext="{Binding SelectedAuthors}">  
  41.             <Grid.ColumnDefinitions>  
  42.                 <ColumnDefinition></ColumnDefinition>  
  43.                 <ColumnDefinition></ColumnDefinition>  
  44.                 <ColumnDefinition></ColumnDefinition>  
  45.                 <ColumnDefinition></ColumnDefinition>  
  46.             </Grid.ColumnDefinitions>  
  47.             <Grid.RowDefinitions>  
  48.                 <RowDefinition Height="auto"></RowDefinition>  
  49.                 <RowDefinition Height="auto"></RowDefinition>  
  50.                 <RowDefinition Height="auto"></RowDefinition>  
  51.                 <RowDefinition Height="auto"></RowDefinition>  
  52.                 <RowDefinition Height="auto"></RowDefinition>  
  53.             </Grid.RowDefinitions>  
  54.             <TextBlock Grid.Row="0"  Grid.Column="0" Text="C# Corner Top 10 Contributions"  FontSize="30" Grid.ColumnSpan="5" Margin="5,10,5,10"></TextBlock>  
  55.    
  56.    
  57.             <StackPanel Orientation="Horizontal" Grid.Row="1"  Grid.Column="0" Margin="5">  
  58.                 <TextBlock Grid.Row="1"  Grid.Column="0" Text="Articles"></TextBlock>  
  59.                 <TextBlock Grid.Row="1"  Grid.Column="0" Text="{Binding Articles}" Margin="5,0,0,0"></TextB  
  60. ock>  
  61.             </StackPanel>  
  62.             <StackPanel Orientation="Horizontal" Grid.Row="1"  Grid.Column="1" Margin="5" >  
  63.                 <TextBlock Grid.Row="1"  Grid.Column="1" Text="Blogs "></TextBlock>  
  64.                 <TextBlock Grid.Row="1"  Grid.Column="1" Text="{Binding Blogs}" Margin="5,0,0,0"></TextBl  
  65. ck>  
  66.             </StackPanel>  
  67.             <StackPanel Orientation="Horizontal" Grid.Row="1"  Grid.Column="2" Margin="5">  
  68.                 <TextBlock Grid.Row="1"  Grid.Column="2" Text="News"></TextBlock>  
  69.                 <TextBlock Grid.Row="1"  Grid.Column="2" Text="{Binding News}" Margin="5,0,0,0"></TextBl  
  70. ck>  
  71.             </StackPanel>  
  72.             <StackPanel Orientation="Horizontal" Grid.Row="1"  Grid.Column="3" Margin="5">  
  73.                 <TextBlock Grid.Row="1"  Grid.Column="3" Text="Resources"></TextBlock>  
  74.                 <TextBlock Grid.Row="1"  Grid.Column="3" Text="{Binding Resources}" Margin="5,0,0,0"></T  
  75. xtBlock>  
  76.             </StackPanel>  
  77.             <StackPanel Orientation="Horizontal" Grid.Row="2"  Grid.Column="0" Margin="5">  
  78.                 <TextBlock Grid.Row="2"  Grid.Column="0" Text="Tutorials"></TextBlock>  
  79.                 <TextBlock Grid.Row="2"  Grid.Column="0" Text="{Binding Tutorials}"  Margin="5,0,0,0"></Te  
  80. tBlock>  
  81.             </StackPanel>  
  82.             <StackPanel Orientation="Horizontal" Grid.Row="2"  Grid.Column="1" Margin="5">  
  83.                 <TextBlock Grid.Row="2"  Grid.Column="1" Text="Forum Posts"></TextBlock>  
  84.                 <TextBlock Grid.Row="2"  Grid.Column="1" Text="{Binding Tutorials}" Margin="5,0,0,0"></Tex  
  85. Block>  
  86.             </StackPanel>  
  87.             <StackPanel Orientation="Horizontal" Grid.Row="2"  Grid.Column="2" Margin="5">  
  88.                 <TextBlock Grid.Row="2"  Grid.Column="2" Text="Downloads"></TextBlock>  
  89.                 <TextBlock Grid.Row="2"  Grid.Column="2" Text="{Binding Downloads}" Margin="5,0,0,0"></  
  90. extBlock>  
  91.             </StackPanel>  
  92.             <StackPanel Orientation="Horizontal" Grid.Row="2"  Grid.Column="3" Margin="5">  
  93.                 <TextBlock Grid.Row="2"  Grid.Column="3" Text="Book Chapters"></TextBlock>  
  94.                 <TextBlock Grid.Row="2"  Grid.Column="3" Text="{Binding BookChapters}" Margin="5,0,0,0">  
  95. /TextBlock>  
  96.             </StackPanel>  
  97.             <StackPanel Orientation="Horizontal" Grid.Row="3"  Grid.Column="0" Margin="5">  
  98.                 <TextBlock Grid.Row="3"  Grid.Column="0" Text="Photos "></TextBlock>  
  99.                 <TextBlock Grid.Row="3"  Grid.Column="0" Text="{Binding Photos}" Margin="5,0,0,0"></TextB  
  100. ock>  
  101.             </StackPanel>  
  102.             <StackPanel Orientation="Horizontal" Grid.Row="3"  Grid.Column="1" Margin="5">  
  103.                 <TextBlock Grid.Row="3"  Grid.Column="1" Text="Videos"></TextBlock>  
  104.                 <TextBlock Grid.Row="3"  Grid.Column="1" Text="{Binding Videos}" Margin="5,0,0,0"></TextB  
  105. ock>  
  106.             </StackPanel>  
  107.             <StackPanel Orientation="Horizontal" Grid.Row="3"  Grid.Column="2" Margin="5">  
  108.                 <TextBlock Grid.Row="3"  Grid.Column="2" Text="Interview Questions"></TextBlock>  
  109.                 <TextBlock Grid.Row="3"  Grid.Column="2" Text="{Binding InterviewQuestions}" Margin="5,0,0,0"></TextBlock>  
  110.             </StackPanel>  
  111.               
  112.         </Grid>  
  113.    
  114.     </Grid>  
  115. </Window