Xamarin Forms MVVM
Introduction to the MVVM Pattern in Xamarin covering the project structure, data binding and changes to property values.
Update: This is applicable for .NET MAUI as well.
This tutorial requires a basic knowledge of C# and Xamarin. Some practice in UI design using XAML and Xamarin Forms is also recommended.
MVVM: Model-View-ViewModel
MVVM is a pattern. What’s that, you say?
Patterns (and practices) are blessings from our annoyed forefathers who spent too much time facing the same problems over and over. You can think of them as half-baked recipes that you need to throw your own ingredients in to complete.
Patterns provide you with a “way of coding” to avoid common problems regarding complexity.
For the case of MVVM, it is a pattern that allows for the separation of the user interface of your application from the business logic.
UI: The code that make pretty screens and buttons
Business Logic: The code that makes the buttons actually do something
Without any kind of separation like MVVM, a typical Xamarin application would have a UI.xaml
file for the GUI and an accompanying UI.xaml.cs
file holding the logic that will run when a user interacts with the UI.
Structure of the Pattern
With the application of MVVM, the project structure is broken into three areas:
- Models: A class used to represent data
- Views: The GUI of an application
- ViewModel: The business logic that runs when an action is taken
Let’s Code
Fire up Visual Studio and create a new Xamarin Forms (Portable) project to begin with.
Our goal is to create a simple BMI calculator.
All the files and codes will be in the portable shared project for this tutorial
Project Structure
Create three new folders as follows:
- /Models
- /Views
- /ViewModels
This directly correlates to the MVVM pattern.
Model
Create a class in the /Models
folder.
This model represents the data required when calculating a BMI. Depending on your application, such classes sometimes can represent your database models directly.
|
|
View
Create a Content Page in the /Views
folder.
|
|
ViewModel
Create a class in the /ViewModels
folder.
The view-model is responsible for populating the view with data from the model. It also contains the logic behind operations triggered from the view. Logically, every input and output field in the view would need a corresponding element (variable) in the view-model.
|
|
Bindings
At the moment, the view and view-model are completely separate files in the project. The view and the elements in the view need to be informed of the existence of the view-model (or vice-versa) to connect the two.
Binding Context
First and foremost, we need a binding context, which essentially tells the view that it needs to link up to its view-model. This can be done directly in xaml
file, or via the xaml.cs
(code-behind) file.
We will go for xaml.cs
in this tutorial.
|
|
Data Binding
The view is now bound to the view-model, but something is still missing. Similar to the binding context, the view components (Entry Boxes, Labels etc.) also need to bind themselves to the variables in the view-model.
Let’s set up the data-binding in the view.
|
|
Command Binding
Take a moment to celebrate - things are moving along nicely.
The only thing left is the Button, and luckily MVVM allows you to treat Buttons very similarly to other elements like Labels - i.e. using bindings. For that, we will make use of the ICommand Property.
Simply put, one can set the value of an ICommand Property to be a function - hence, when that property is read, the function is returned.
Think of ICommands as a way to expose functions as a variable.
This allows us to bind a function to a button, just like the other elements were bound to their counterparts in the view-model.
Create an ICommand in the View-Model.
|
|
Read more on Lambda Expressions if you are unfamiliar with the code syntax above.
Finally, update the view to bind the command to your button.
|
|
Property Changes
Looks like everything is in place - the application should run, right?
Go ahead and try to run it, and click on the button.
Face that crash and burn like a proper developer.
That’s right, clicking on the button does nothing.
Here’s the deal.
Everything was coded and bound, but one problem remains. We cannot expect the application to spend all of its precious resources constantly surveying all the elements and variables in the codebase waiting for a change.
The solution - INotifyPropertyChanged.
This is a means to inform the application when something changes for it to taking necessary steps and refresh the elements on the screen.
Update the view-model code as below.
|
|
The PropertyChanged variable acts as an agent between the view and the view-model, keeping track of what values are changing.
- When PropertyChanged is null – it implies nothing has changed.
- Setting a value to PropertyChanged triggers an update the view.
So, our next step is to ensure that we update the PropertyChanged variable when something changes.
Create a method in the view-model, designed to update the PropertyChanged variable when it is called.
|
|
Lastly, update the data variables (the ones that populate the screen) to call our method when a change happens.
|
|
It’s a wrap (or a taco)
Give the application a spin.
This was an introduction to MVVM and how you can easily set it up to decouple your logic from your front-end. There is more to it, but for now, grab a taco and congratulate yourself for a job well done.
Credits
Cover Image: Photo by Nathan Da Silva on Unsplash