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
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
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).
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
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
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
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 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’ keywords in the XAML which is used to bind the control data to the relevant view-model properties, but this still wont 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 direct 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
this.BindingContext = new viewmodels.ViewModel1();
which will now match the following
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 Dependancy 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.
See you for the next MVVM chapter
Steve