Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Mobile / Xamarin

MVVM and Xamarin Forms

0.00/5 (No votes)
3 Dec 2019CPOL4 min read 22.1K  
In this post, I will cover what MVVM is and how it can be used from a pure .NET perspective by creating a basic MVVM framework from scratch.

Introduction

As a Xamarin forms developer creating multiple applications, I get a lot of questions regarding MVVM and how to effectively use this programming pattern with XAML.

Background

In this post, I will cover what MVVM is and how it can be used from a pure .NET perspective by creating a basic MVVM framework from scratch. I create a very basic example of how to do this yourself in under 10 minutes and the source code will be available via my github repo.

What is MVVM

The MVVM pattern allows a developer to easily separate out the visual view from the business logic and data models.

MVVM = Model – View – Viewmodel

This separation can be clearly seen.

Image 1

MVVM Component Parts

The Model: The model is the data that is used within the application. This can be a simple array or a collection of data, a database or even data from a web based service such as Azure.

The View: This is the visual front end that the user sees and interacts with. This is usually referred to as views, UI component or front-end, etc. This is what the user visually sees and interacts with via pages and controls. The views’ data is bound and synchronizes via the view-model.

The View-Model: In other programming patterns, this is often referred to as the presenter or controller. In MVVM, the view-model is the glue between the view and the model, and handles all interactions such as button clicks and data updates on the View (UI).

Image 2

TIP: One area of the MVVM pattern that I’ve seen confuse lots of developers is that of update notification on the view. The view is populated only once and this is during initialization of the view, at this point any view data bindings get populated via the bound view-model properties.

So unless we create a mechanism to inform the view we have an update, any data changes within the view-model (after the initial binding) will not be propagated to the front end view, which would be a problem for users.

How We Create Notification Events

We can implement this notification trigger very easily using a built in .NET ‘INotifyPropertyChanged’ interface as follows:

First, we create our sample base class based on the INotifyPropertyChange interface and implement the ‘OnPropertyChange’ function together with an exposed public event handler.

C#
public class BaseModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

Now within our view-model, we simply inherit this new base class and we call the ‘OnPropertyChanged’ method when we have any data updates.

  • Now let us create a simple data model so we can bind some data in the view.. a simple person class:
    C#
    public class Person
    {
             public int Age { get; set; }
             public string FirstName { get; set; }
             public string LastName { get; set; }
             public string PersonInfo()
                    {    return $"{FirstName} {LastName} Age:{Age}"  ;  }
    }
    
  • Now create a View-model based on our base class that implements some simple properties based on the new ‘Person’ model object. Note how we call ‘OnPropertyChange’ on a value change.
    C#
      public class ViewModel1:BaseModel
    {
              private Person _person;
               public ViewModel1()
               {
                          // set some default here for example
                          _person = new Person
                          {
                                     Age = 21,
                                     FirstName = "Steve",
                                     LastName = "Hawkins"
                          };
               }
    
             public int Age
               {
                          get { return _person.Age; }
                          set {
                                     _person.Age = value;
                                     OnPropertyChanged("Age");
                                     OnPropertyChanged("UserInfo");
                              }
               }
    
             public string FirstName
               {
                          get { return _person.FirstName; }
                          set
                          {
                                     _person.FirstName = value;
                                     OnPropertyChanged("FirstName");
                                     OnPropertyChanged("UserInfo");
                          }
               }
    
             public string LastName
               {
                          get { return _person.LastName; }
                          set
                          {
                                     _person.LastName = value;
                                     OnPropertyChanged("LastName");
                                     OnPropertyChanged("UserInfo");
                          }
               }
    
             public string UserInfo
               {
                          get { return _person.PersonInfo(); }
               }
    }
    

Note again the ‘OnPropertyChange()’ calls to our ‘INotifyPropertyChange’ base class. This is the mechanism that tells the view we have an update and to update the binding data.

We now need our XAML view to display the view-model data and auto update when the view-model data has been modified.

For the UI, create a new XAML Page view and open the XAML source code. Now add the following XAML code for the controls and data bindings:

XML
    <?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"  
 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
 x:Class="INotfySource.views.MainView"  BackgroundColor="White">
 <ContentPage.Content>
         <StackLayout>
                  <Label Text="FirstName: " HorizontalOptions="Start" 
                   TextColor="Black" FontSize="Medium" /> 
                  <Editor Text="{Binding FirstName}" HorizontalOptions="CenterAndExpand" 
                   TextColor="Black" /> 
                  <Label Text="LastName: " HorizontalOptions="Start" 
                   TextColor="Black" FontSize="Medium" /> 
                  <Editor Text="{Binding LastName}" HorizontalOptions="CenterAndExpand" 
                   TextColor="Black" /> 
                  <Label Text="Age: " HorizontalOptions="Start" 
                   TextColor="Black" FontSize="Medium" /> 
                  <Editor Text="{Binding Age}" HorizontalOptions="CenterAndExpand" 
                   TextColor="Black" /> 
                  <Label Text="{Binding UserInfo}" HorizontalOptions="StartAndExpand" 
                   TextColor="Black" FontSize="Large" /> 
         </StackLayout> 
</ContentPage.Content> 
</ContentPage>

Note the ‘Binding’ keyword in the XAML which is used to bind the control data to the relevant view-model properties, but this still won't work as we expect just yet... we still have one more step to ensure we bind our data. This is the binding of the view-model to the view.

We still have one more step to implement before the data will bind correctly. This step binds the page context to the view-model.

We can do this in the XAML code directly using the XAML <contentpage:bindingcontext> tags but I will show you how to do this using the code behind method.

Open the ‘MainView.cs’ file and add the code:

C#
this.BindingContext = new viewmodels.ViewModel1();

which will now match the following:

C#
public partial class MainView : ContentPage
{
         public MainView ()
         {
               InitializeComponent ();

              // set binding context here
              this.BindingContext = new viewmodels.ViewModel1();
         }
}

This will hook everything up using our MVVM architecture and by compiling and running the app, you will see a simple layout in which you can modify the firstname, lastname and age fields to see a dynamic update within the info field (last field on page) which is performed direct from the view-model.

This technique works brilliant for simple applications but we hit issues when we need to implement advanced techniques such as Dependency Injection or Inversion of control.

But there is a simple solution for this issue and that is to use one of the supported MVVM Frameworks for Xamarin Forms. In the next article, I’ll modify this project and implement the solution using the MVVM Lite framework.

History

  • 3rd December, 2019: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)