In this article we are going to see simple implementation of MVVM pattern in WPF application. For the sake of simplicity, we'll be showing the list of users and will get detailed explanation of the process followed behind the scene.
First create a WPF application and name it as "SimpleMVVMApp" and add three folders (Model, ViewModel, and Views) into your project, after which our application will look as shown in the following screenshot.
![](http://findnerd.s3.amazonaws.com/imagedata/7195/7195.png)
Let's understand this MVVM architecture while adding components of MVVM in following steps:
- Model - This folder will contain simple class objects that will represent actual data in the application. They shouldn't be containing any data manipulation logic, event handling, business logic or any of that stuff. An example of a model could be a Person entity having first name, last name, age etc.
In our application as we are planning to show the list of users so we would need an entity which could be further used as a list item. So let's add class file UserModel.cs inside Model folder and paste the below code in that class.
using System.ComponentModel;
namespace SimpleMVVMApp.Model
{
public class UserModel : INotifyPropertyChanged
{
private string _name;
public string Name
{
get { return _name; }
set
{
_name = value;
RaisePropertyChanged("Name");
}
}
private int _age;
public int Age
{
get { return _age; }
set
{
_age = value;
RaisePropertyChanged("Age");
}
}
protected void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
public event PropertyChangedEventHandler PropertyChanged;
}
}
-
ViewModel - The ViewModel might consist of Commands, properties that are being reflected in the view. Commands will basically handle the events from the view and properties could be a collection of object or a single object. Collection of object in case we are showing the list in a grid or single object in case we are showing a detail of any object like person.
Add class file UserViewModel.cs inside ViewModel folder and paste the below code in that class.
using SimpleMVVMApp.Model;
using System.Collections.ObjectModel;
namespace SimpleMVVMApp.ViewModel
{
public class UserViewModel
{
// Collection of users to be shown in the View in the form of a list
public ObservableCollection<UserModel> Users { get; set; }
public UserViewModel()
{
Users = new ObservableCollection<UserModel>();
LoadUsers();
}
public void LoadUsers()
{
ObservableCollection<UserModel> users = new ObservableCollection<UserModel>();
users.Add(new UserModel { Name = "Mark", Age = 20 });
users.Add(new UserModel { Name = "Allen", Age = 25 });
users.Add(new UserModel { Name = "Linda", Age = 23 });
Users = users;
}
}
}
Here we have an ObservableCollection of UserModel type, which is going to hold the list of users. For the sake of simplicity LoadUsers() function is dealing with static list but in real application, it would fetch list of users from the database. In our application property Users will be used as an item source.
-
View - This folder will contain the views which displays information and allow users to access the application. Following MVVM pattern, the views will hold the reference of ViewModel, it needs access to. The View generally displays information by binding to entities defined in ViewModel.
In our example we have a ObservableCollection of UserModel entity defined in UserViewModel.cs, as we are going to have a view which will be showing the list of users by binding to the properties of UserModel. It also require our view to have a reference of UserViewModel class.
Let's add a new User Control (WPF) in Views folder and give it a name as UserView.xaml and paste the below code in XAML file.
<UserControl x:Class="SimpleMVVMApp.Views.UserView"
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:local="clr-namespace:SimpleMVVMApp.Views"
xmlns:ViewModel="clr-namespace:SimpleMVVMApp.ViewModel"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<ViewModel:UserViewModel/>
</UserControl.DataContext>
<Grid>
<StackPanel HorizontalAlignment = "Center">
<ItemsControl ItemsSource = "{Binding Path = Users}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation = "Horizontal">
<TextBlock Text = "{Binding Path = Name, Mode = TwoWay}"
Width = "100" Margin = "3 5 3 5"/>
<TextBlock Text = "{Binding Path = Age, Mode = TwoWay}"
Width = "100" Margin = "0 5 3 5"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</UserControl>
In the above xaml code, refer to the following line
xmlns:ViewModel="clr-namespace:SimpleMVVMApp.ViewModel"
Here we have added a namespace "ViewModel" which points to the location where we have UserViewModel defined. Having defined this we would be able to specify the DataContext using the following syntax.
<UserControl.DataContext>
<ViewModel:UserViewModel/>
</UserControl.DataContext>
Now though we have created required components for Model, View and ViewModel but if you will try to run the application, you will not see anything in the screen. That's because by default MainWindow.xaml gets rendered as defined in the App.xaml file StartupUri="MainWindow.xaml".
So let's open MainWindow.xaml file and replace its content with following code.
<Window x:Class="SimpleMVVMApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SimpleMVVMApp"
mc:Ignorable="d"
xmlns:Views="clr-namespace:SimpleMVVMApp.Views"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Views:UserView/>
</Grid>
</Window>
In the above xaml code, refer to the following line
xmlns:Views="clr-namespace:SimpleMVVMApp.Views"
Here we have added a namespace "Views" which points to the location where we have a View defined. Having defined this namespace now we would be able to specify the UserView and get it rendered inside MainWindow.xaml.
<Grid>
<Views:UserView/>
</Grid>
Let's run our application and we can see the list of users in the very first screen.
![](http://findnerd.s3.amazonaws.com/imagedata/7200/7200.png)
Okay so now you got some idea about MVVM pattern, wouldn't it be better to have a look at some of the advantages of using MVVM pattern.
Few advantages of using MVVM pattern are as follows:
- Following this pattern it is easier to share a project with the UI designer (XAML designer). It gives the flexibility for design and development task to happen simultaneously.
- It is easier to change the user interface elements without having to refactor the logic in the related code base.
- It is easier to write thorough unit test cases because views are not tightly coupled with the functionalities.
- It allows us to create a reusable components and use them across different projects.
Note: For the time being you may ignore interface INotifyPropertyChanged and its related implementation in UserModel.cs file.
0 Comment(s)