Understanding the basics of MVVM design pattern

This article is dedicated for beginners who would like to know more about Model-View-ViewModel (MVVM) design pattern and why MVVM has to be used.

Why use MVVM?

In traditional UI development - developer used to create a View using window or user control or page and then write all logical code (Event handling, initialization and data model, etc.) in the code behind and hence they were basically making code as a part of view definition class itself. This approach increased the size of the View class and created a very strong dependency between my UI and data binding logic and business operations. In this situation, no two developers can work simultaneously on the same view and also one developer's changes might break the other code. So everything is in one place is always a bad idea for maintainability, extendibility and testability prospective. So if you look at the big picture, you can feel that all these problems exist because there is a very tight coupling between the following items.

  1. View (UI)
  2. Model (Data displayed in UI)
  3. Glue code (Event handling, binding, business logic)

In MVVM the Glue code is View Model. So it basically focuses on separation of concerns to make the implementation of an application structure a lot more simpler to create as well as maintain.

If property values in the ViewModel change, those new values automatically propagate to the view via data binding and via notification. When the user performs some action in the view for example clicking on save button, a command on the ViewModel executes to perform the requested action. In this process, it’s the ViewModel which modifies model data, View never modifies it. The view classes have no idea that the model classes exist, while the ViewModel and model are unaware of the view. In fact, the model doesn’t have any idea about ViewModel and view exists.

What is MVVM?

The MVVM pattern includes three key parts:

  1. Model (Business rule, data access, model classes)
  2. View (User interface (XAML))
  3. ViewModel (Agent or middle man between view and model)

 

The ViewModel acts as an interface between Model and View. It provides data binding between View and model data as well as handles all UI actions by using command.

The View binds its control value to properties on a ViewModel, which, in turn, exposes data contained in Model objects.

mvvm

A simple representation of MVVM design pattern for a news reader application

news-reader 

A simple MVVM implementation example in C#

Here is a simple code implementation example in C#:

Model:

 public class Book   
{
        public string Title { get; set; }
        public string Author { get; set; }
        public string Category { get; set; }
        public string Language { get; set; }
}

View Model:

 public class MainPageViewModel : BindableBase
   {
       private List<Book> books;
       public List<Book> Books         
      { 
           get
           {
            return books;
           } 
           set
           {
            SetProperty(ref books, value);
           } 
       public MainPageViewModel()
       {
           Books = new List<Book>();
           Books.Add(new Book
               {
                   Title = “Harry Potter”, 
                   Author = “J. K. Rowling”,
                   Category = “Young-adult fiction”,
                   Language = “English”
               });
           Books.Add(new Book
           {
                   Title = “Written Lives”, 
                   Author = “Javier Marias”,
                   Category = “Biography”,
                   Language = “Spanish”
           });
   }
}

BindableBase Class:

 public class BindableBase : INotifyPropertyChanged
    {
          ///
        /// Multicast event for property change notifications.
        ///
        public event PropertyChangedEventHandler PropertyChanged;

        ///
        /// Checks if a property already matches a desired value.  Sets the property and
        /// notifies listeners only when necessary.
        ///
        ///Type of the property.
        ///Reference to a property with both getter and setter.
        ///Desired value for the property.
        ///Name of the property used to notify listeners.  This
        /// value is optional and can be provided automatically when invoked from compilers that
        /// support CallerMemberName.
        ///True if the value was changed, false if the existing value matched the
        /// desired value.
        protected bool SetProperty(ref T storage, T value, [CallerMemberName] String propertyName = null)
        {
            if (object.Equals(storage, value)) return false;

            storage = value;
            this.OnPropertyChanged(propertyName);
            return true;
        }

        ///
        /// Notifies listeners that a property value has changed.
        ///
        ///Name of the property used to notify listeners.  This
        /// value is optional and can be provided automatically when invoked from compilers
        /// that support .
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            var eventHandler = this.PropertyChanged;
            if (eventHandler != null)
            {
                eventHandler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

View:

 <TextBlock x:Name="bookTitle” HorizontalAlignment="Left" TextWrapping="Wrap"
 Text="{Binding Title}" VerticalAlignment="Top"/>

<TextBlock x:Name="bookAuthor” HorizontalAlignment="Left" TextWrapping="Wrap"
 Text="{Binding Author}" VerticalAlignment="Top" Margin="0,142,0,0"/>

<TextBlock x:Name="bookCategory” HorizontalAlignment="Left" TextWrapping="Wrap"
 Text="{Binding Category}" VerticalAlignment="Top" Margin="0,242,0,0"/> 

<TextBlock x:Name="bookLanguage” HorizontalAlignment="Left" TextWrapping="Wrap" 
 Text="{Binding Language}" VerticalAlignment="Top" Margin="0,342,0,0"/> 
  

If property values in the ViewModel change, those new values automatically propagate to the view via data binding and via notification. When the user performs some action in the view for example clicking on save button, a command on the ViewModel executes to perform the requested action. In this process, it’s the ViewModel which modifies Model data, View never modifies it. The View classes have no idea that the Model classes exist, while the ViewModel and model are unaware of the View. In fact, the Model doesn’t have any idea about ViewModel and View exists.

References:

https://www.codeproject.com/Articles/186705/A-Totally-Simple-Introduction-to-the-MVVM-Concept

https://russelleast.wordpress.com/2008/08/09/overview-of-the-modelview-viewmodel-mvvm-pattern-and-data-binding/

https://msdn.microsoft.com/en-us/magazine/dd419663.aspx