Introduction to the MVVM Pattern

I remember back when I was interested in learning MVVM for the first time, I had some difficulties due to the sheer number of resources out there and each one of them explaining a different portion of MVVM. In this blog post, I’ll try give you an an easy to understand view of MVVM basics along with a concrete example.

What is MVVM?

MVVM stands for Model-View-ViewModel. It has similar concepts to the Model-View-Controller and Model-View-Presenter patterns, but I’ll assume that you’re familiar with neither. MVVM at its core serves to create a separation of concerns, taking the user interface, the view logic and the business logic and explicitly distinguishing them from each other.
 
 As you’ll see soon enough, each component of the MVVM pattern is there to do a certain and distinct job. Each component directly interacts with each other in useful manner, but looking at it from a higher level the model should be unaware of the viewmodel and in turn the viewmodel unaware of the view.
 MVVM comes inherently to XAML based applications since MVVM takes advantage of some XAML notions, such as data binding and commands; both of which I’ll be showing in my example further down.

Model

The model is responsible for the business logic of your application. It contains the actual data of any object that your application might be dealing with. To put things into perspective, a model could be a Student class, which contains different properties such as a student’s name, date of birth, grade and so forth.
 This is all the model cares for and precisely what it should know about. A model should not contain behaviors on how the data is manipulated, retrieved or altered. In addition, it should not care about how the data it represents will be projected on the view, nor if it will be shown at all.
 As I said earlier, models are not aware of anyone else. When a model’s properties change, it somehow needs to notify anyone that might be interested in this change. What it does is broadcast a message saying something along the lines of “Hey, one of my properties has changed” and whoever’s interested will be able to listen to that. This is achieved through the INotifyPropertyChanged interface, which we’ll see later on.

View

The view is the easiest component of MVVM for newcomers to grasp. It is what the end user sees on his screen and what he interacts with. It is responsible for taking any data in your application and present it to the user in a friendly manner.
 Moreover, the view is responsible for handling any events that might occur, such as mouse clicks or key presses. It can choose to either handle these events solely or propagate them to the viewmodel which will in turn handle them using its own logic.
 A view should have just one viewmodel, either its own or one inherited from its parent’s viewmodel. The view is written purely in XAML and interacts with the viewmodel using (but not only) data bindings and commands.

ViewModel

The viewmodel is the middleman between the view and the model. It describes the interaction logic of the view and exposes properties that can be used by the view.
 It is responsible for storing the current state of the view through methods and properties and manipulate any application data based on events received by the view. While the viewmodel is directly interacting with the view, it should be designed in a way such that it is not aware of the view.
 You can think of the viewmodel as a state of the data in the model.

An example application using MVVM

Code-Behind

In the following example we will be building an application which will allow us to create new students and add them to a table. I’m assuming you’re familiar with XAML & C# syntax and will not go in depth into concepts such as Data Binding or Commands. MSDN has some great articles on the aforementioned here and here, respectively
 First off, let’s create the model which will hold the information about a student.

public class StudentModel : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private string _firstName; public string FirstName { get { return _firstName; } set { _firstName = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(nameof(FirstName))); } } private string _lastName; public string LastName { get { return _lastName; } set { _lastName = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(nameof(LastName))); } } private string _course; public string Course { get { return _course; } set { _course = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(nameof(Course))); } } private double _numericalGrade; public double NumericalGrade { get { return _numericalGrade; } set { _numericalGrade = value; if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(nameof(NumericalGrade))); } } }

Ignoring the highlighted lines, this is a class with four properties describing a simple student.
 Remember when I was explaining the model and I mentioned the message the model will send each time one of its properties changes? That’s achieved in the highlighted lines.
 First, the class should derive from the INotifyPropertyChanged (line 1) and then implement its event signature (line 3). Next up, each time our property is Set we call the PropertyChanged event to broadcast this “message” along with an appropriate null check.
 That’s our model, completed.

Before moving on to the viewmodel, we have to create a wrapper for the ICommand interface which will allow us to create commands in the viewmodel which can be exposed to the view.

public class RelayCommand : ICommand { public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } readonly Action<object> _execute; readonly Predicate<object> _canExecute; public RelayCommand(Action<object> execute, Predicate<object> canExecute = null) { if (execute == null) throw new ArgumentException(nameof(execute)); _execute = execute; _canExecute = canExecute; } public bool CanExecute(object parameter) => _canExecute == null ? true : _canExecute(parameter); public void Execute(object parameter) { _execute(parameter); } }

I will not go into detail about the implementation of this command wrapper but just know that RelayCommand can be instantiated with two parameters; the first being an Action, describing what this command will do and the second being a Predicate, which will determine whether this command can be executed.

Now that I have my ICommand wrapper sorted, I can implement my viewmodel which I’ll call MainViewModel.cs.

First thing I’ll add to my viewmodel is a collection that will hold all of my students. This collection needs to be of type ObservableCollection, which will take up the job of notifying the view each time the contents of the collection change:

private ObservableCollection<StudentModel> _studentCollection = new ObservableCollection<StudentModel>(); public ObservableCollection<StudentModel> StudentCollection { get { return _studentCollection; } set { _studentCollection = value; } }

I also need a property which will hold the new student I’ll be creating:

private StudentModel _student = new StudentModel(); public StudentModel Student { get { return _student; } set { _student = value; } }

Finally, all I need now is the command which will allow me to add a new student to the collection:

public RelayCommand AddStudentCommand => new RelayCommand(p => AddStudent(), p => CanAddStudent()); private void AddStudent() { StudentCollection.Add(new StudentModel(Student)); } private bool CanAddStudent() => !(string.IsNullOrWhiteSpace(Student.FirstName) || string.IsNullOrWhiteSpace(Student.LastName) || string.IsNullOrWhiteSpace(Student.Course) );

Notice on line 5 I’m adding a new StudentModel to the collection. This is because classes are passed by reference and I need to create a new object each time I want to add a new student, else I’d be altering and adding the same student each time. Of course, you will need to add the relevant constructor to the StudentModel class which takes a StudentModel as a parameter and copies its properties.
 On lines 8 to 10, you can see the predicate I was talking about in my RelayCommand implementation. This will not allow the command to execute (that is, add a student to the collection) if the student does not have a first name, last name or course. What’s great is that XAML will automatically disable the button associated with this command when the command can not execute.

All that’s left now is our user interface, the view. Easy, right?

XAML

I’ll start off by implementing my UI in MainWindow.xaml

<Window x:Class="MVVM_Basics_Example_WPF.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:local="clr-namespace:MVVM_Basics_Example_WPF" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:vm="clr-namespace:MVVM_Basics_Example_WPF.ViewModels" Title="MainWindow" mc:Ignorable="d"> <Window.DataContext> <vm:MainViewModel /> </Window.DataContext> ... </Window>

First thing we need to do in the view is wire it to our viewmodel. This is done by assigning an instance of the viewmodel to the view’s DataContext property. First, we’ll add a reference to my viewmodels folder in line 7 and then I assign it to the data context in line 11. We could have also assigned the viewmodel in code, but doing it this way allows intellisense to be aware of the viewmodel’s exposed properties.

Now, let’s create some text boxes which will allow us to enter student details.

<Label Content="First Name" /> <TextBox Grid.Column="1" Text="{Binding Student.FirstName}" /> <Label Grid.Row="1" Content="Last Name" /> <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Student.LastName}" /> <Label Grid.Row="2" Content="Course" /> <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Student.Course}" /> <Label Grid.Row="3" Content="Numerical Grade" /> <TextBox Grid.Row="3" Grid.Column="1" Text="{Binding Student.NumericalGrade}" />

You can see in the highlighted lines that I’m binding the text property of the textbox to the Student property defined on the viewmodel and in turn the relevant properties of that student model. If you’re following along, you’ll also notice that intellisense is picking all this up. Isn’t that just awesome?

Now, we need a button to which we’ll hook up our command. Almost identical to previously, instead this time we’re binding to the Command property:

<Button Command="{Binding AddStudentCommand}" Grid.Row="4" Grid.Column="1" Content="Add" />

One more thing and we’re done. Let’s add a DataGrid which will be bound to our student collection. The data grid takes care of finding all properties in the model and automatically generates columns for each one of them. Incredible!

<DataGrid Grid.Row="5" Grid.ColumnSpan="2" Width="368" ItemsSource="{Binding StudentCollection}" />

And we’re done! The result:

Notice in the screenshot that the first three fields are empty and the add button is disabled. Did we write that behaviour in our view? Nope! It’s all thanks to the command that we wrote in the viewmodel.
 I hope I was able to give you some understanding of MVVM, at least on a basic level. There are many more advanced topics to learn regarding MVVM and the different ways to implement it, some of which I’ll be discussing in future blog posts. Either way, you should now be ready to delve deeper into this amazing pattern.

As always, you can find the complete source code for this application on GitHub right here.


Originally published at blogsharp.net on February 12, 2016.