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.
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
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 .
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.
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.
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.
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.
- using System;
- using System.Collections.Generic;
- using System.Collections.ObjectModel;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
-
- namespace MVVM_Sample.Model
- {
- public class Authors
- {
-
-
- #region " AuthorsName Property "
-
-
-
- public string Name { get; set; }
- #endregion
-
- #region " Articles Property "
-
-
-
- public string Articles { get; set; }
- #endregion
-
- #region " Blogs Property "
-
-
-
- public string Blogs { get; set; }
- #endregion
-
- #region " News Property "
-
-
-
- public string News { get; set; }
- #endregion
- #region " Resources Property "
-
-
-
- public string Resources { get; set; }
- #endregion
-
- #region " Tutorials Property "
-
-
-
- public string Tutorials { get; set; }
- #endregion
-
- #region " Forum Posts Property "
-
-
-
- public string ForumPosts { get; set; }
- #endregion
-
- #region " Downloads Property "
-
-
-
- public string Downloads { get; set; }
- #endregion
-
- #region " Book Chapter Property "
-
-
-
- public string BookChapter { get; set; }
- #endregion
-
- #region " Photos Property "
-
-
-
- public string Photos { get; set; }
- #endregion
-
- #region " Videos Property "
-
-
-
- public string Videos { get; set; }
- #endregion
-
- #region " Interview Questions Property "
-
-
-
- public string InterviewQuestions { get; set; }
- #endregion
-
- #region " About Authors Property "
-
-
-
- public string About { get; set; }
- #endregion
-
- #region " Authors Ranks Property "
-
-
-
- public string Ranks { get; set; }
- #endregion
-
- #region " Point Property "
-
-
-
- public string Point { get; set; }
- #endregion
-
- #region " Country Property "
-
-
-
- public string Country { get; set; }
- #endregion
-
-
-
-
- public string image { get; set; }
- public static ObservableCollection<Authors> GetAuthorsRecord()
- {
- ObservableCollection<Authors> AuthorsRecords = new ObservableCollection<Authors>
- {
- 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",
- About="Mahesh Chand is founder of C# Corner. C# Corner founded in 1999 is a
- 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.",
- image="Image/mahesh.png",Ranks="1"},
- 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",
- About="",image="Image/b942f9.gif",Ranks="2"},
- 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",
- About="",image="Image/dbeniwal321.jpg",Ranks="3"},
- 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",
- 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"},
- 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",
- 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"},
- 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",
- 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"},
- 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",
- 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"},
- 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",
- About="Microsoft MVP | Author | IT Faculty | Student of M.Tech. IT | Blogs at ITORIAN.COM",image="Image/abhikumarvatsa.jpg",Ranks="8"},
- 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",
- 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"},
- 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",
- About="",image="Image/suthish_nair.jpg",Ranks="10"},
- };
- return AuthorsRecords;
- }
- }
- }
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 .
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
-
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using MVVM_Sample.Model;
- using System.Collections.ObjectModel;
- namespace MVVM_Sample.ViewModel
- {
- class MainViewModel :INotifyPropertyChanged
- {
- private Authors speaker;
- public ObservableCollection<Authors> _speaker;
- public ObservableCollection<Authors> Listofspeaker
- {
- get
- {
- return _speaker;
- }
- set
- {
- if (_speaker != null)
- {
- _speaker = value;
- PropertyChanged(this, new PropertyChangedEventArgs("Listofspeaker"));
- }
- }
- }
- public Authors SelectedAuthors
- {
- get
- {
- return speaker;
- }
- set
- {
- speaker = value;
- PropertyChanged(this, new PropertyChangedEventArgs("SelectedAuthors"));
- }
- }
- public MainViewModel()
- {
- _speaker = Authors.GetAuthorsRecord();
- }
- #region INotifyPropertyChanged Members
- public event PropertyChangedEventHandler PropertyChanged;
- #endregion
- }
- }
ViewOur 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.
- <Window x:Class="MVVM_Sample.MainWindow"
- xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
- xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
- xmlns:local="clr-namespace:MVVM_Sample.ViewModel"
- Title="MainWindow" Height="350" Width="525" Background="White">
- <Window.DataContext>
- <local:MainViewModel></local:MainViewModel>
- </Window.DataContext>
- <Grid>
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="1*"></ColumnDefinition>
- <ColumnDefinition Width="3*"></ColumnDefinition>
- </Grid.ColumnDefinitions>
-
- <ListBox ItemsSource="{Binding Listofspeaker}" SelectedItem="{Binding SelectedAuthors,Mode=TwoWay}">
- <ListBox.ItemTemplate>
- <DataTemplate>
- <Grid Margin="0,5,0,0">
- <Grid.ColumnDefinitions>
- <ColumnDefinition Width="auto"></ColumnDefinition>
- <ColumnDefinition></ColumnDefinition>
- </Grid.ColumnDefinitions>
- <Image Source="{Binding image}" Height="80" Width="80" Grid.Column="0"></Image>
- <StackPanel Grid.Column="1">
- <TextBlock Text="{Binding FirstName}" Margin="5,1,0,1"></TextBlock>
- <TextBlock Text="{Binding Country}" Margin="5,1,0,1"></TextBlock>
- <StackPanel Orientation="Horizontal">
- <TextBlock Text="Ranks #" Margin="5,1,0,1"></TextBlock>
- <TextBlock Text="{Binding Ranks}" Margin="3,1,0,1"></TextBlock>
- </StackPanel>
- <StackPanel Orientation="Horizontal">
- <TextBlock Text="Point" Margin="5,1,0,1"></TextBlock>
- <TextBlock Text="{Binding Point}" Margin="3,1,0,1"></TextBlock>
- </StackPanel>
- </StackPanel>
- </Grid>
- </DataTemplate>
- </ListBox.ItemTemplate>
- </ListBox >
- <Grid Grid.Column="1" DataContext="{Binding SelectedAuthors}">
- <Grid.ColumnDefinitions>
- <ColumnDefinition></ColumnDefinition>
- <ColumnDefinition></ColumnDefinition>
- <ColumnDefinition></ColumnDefinition>
- <ColumnDefinition></ColumnDefinition>
- </Grid.ColumnDefinitions>
- <Grid.RowDefinitions>
- <RowDefinition Height="auto"></RowDefinition>
- <RowDefinition Height="auto"></RowDefinition>
- <RowDefinition Height="auto"></RowDefinition>
- <RowDefinition Height="auto"></RowDefinition>
- <RowDefinition Height="auto"></RowDefinition>
- </Grid.RowDefinitions>
- <TextBlock Grid.Row="0" Grid.Column="0" Text="C# Corner Top 10 Contributions" FontSize="30" Grid.ColumnSpan="5" Margin="5,10,5,10"></TextBlock>
-
-
- <StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="0" Margin="5">
- <TextBlock Grid.Row="1" Grid.Column="0" Text="Articles"></TextBlock>
- <TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding Articles}" Margin="5,0,0,0"></TextB
- ock>
- </StackPanel>
- <StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="1" Margin="5" >
- <TextBlock Grid.Row="1" Grid.Column="1" Text="Blogs "></TextBlock>
- <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Blogs}" Margin="5,0,0,0"></TextBl
- ck>
- </StackPanel>
- <StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="2" Margin="5">
- <TextBlock Grid.Row="1" Grid.Column="2" Text="News"></TextBlock>
- <TextBlock Grid.Row="1" Grid.Column="2" Text="{Binding News}" Margin="5,0,0,0"></TextBl
- ck>
- </StackPanel>
- <StackPanel Orientation="Horizontal" Grid.Row="1" Grid.Column="3" Margin="5">
- <TextBlock Grid.Row="1" Grid.Column="3" Text="Resources"></TextBlock>
- <TextBlock Grid.Row="1" Grid.Column="3" Text="{Binding Resources}" Margin="5,0,0,0"></T
- xtBlock>
- </StackPanel>
- <StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="0" Margin="5">
- <TextBlock Grid.Row="2" Grid.Column="0" Text="Tutorials"></TextBlock>
- <TextBlock Grid.Row="2" Grid.Column="0" Text="{Binding Tutorials}" Margin="5,0,0,0"></Te
- tBlock>
- </StackPanel>
- <StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="1" Margin="5">
- <TextBlock Grid.Row="2" Grid.Column="1" Text="Forum Posts"></TextBlock>
- <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Tutorials}" Margin="5,0,0,0"></Tex
- Block>
- </StackPanel>
- <StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="2" Margin="5">
- <TextBlock Grid.Row="2" Grid.Column="2" Text="Downloads"></TextBlock>
- <TextBlock Grid.Row="2" Grid.Column="2" Text="{Binding Downloads}" Margin="5,0,0,0"></
- extBlock>
- </StackPanel>
- <StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="3" Margin="5">
- <TextBlock Grid.Row="2" Grid.Column="3" Text="Book Chapters"></TextBlock>
- <TextBlock Grid.Row="2" Grid.Column="3" Text="{Binding BookChapters}" Margin="5,0,0,0">
- /TextBlock>
- </StackPanel>
- <StackPanel Orientation="Horizontal" Grid.Row="3" Grid.Column="0" Margin="5">
- <TextBlock Grid.Row="3" Grid.Column="0" Text="Photos "></TextBlock>
- <TextBlock Grid.Row="3" Grid.Column="0" Text="{Binding Photos}" Margin="5,0,0,0"></TextB
- ock>
- </StackPanel>
- <StackPanel Orientation="Horizontal" Grid.Row="3" Grid.Column="1" Margin="5">
- <TextBlock Grid.Row="3" Grid.Column="1" Text="Videos"></TextBlock>
- <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding Videos}" Margin="5,0,0,0"></TextB
- ock>
- </StackPanel>
- <StackPanel Orientation="Horizontal" Grid.Row="3" Grid.Column="2" Margin="5">
- <TextBlock Grid.Row="3" Grid.Column="2" Text="Interview Questions"></TextBlock>
- <TextBlock Grid.Row="3" Grid.Column="2" Text="{Binding InterviewQuestions}" Margin="5,0,0,0"></TextBlock>
- </StackPanel>
-
- </Grid>
-
- </Grid>
- </Window