MAUI applications using the MVVM pattern.

Andres Zapata
5 min readSep 29, 2023

--

Hi devs, today we are going to learn, how to implement the MVVM pattern in an easy and fast way to MAUI apps.

MVVM is a design pattern that helps separate an application’s user interface (View) from its underlying data and business logic (Model) while introducing an intermediary component (ViewModel) to facilitate communication between the View and Model. It is commonly used in frameworks like WPF (Windows Presentation Foundation), Xamarin, and MAUI to create clean and maintainable UI applications

Model (M): The Model represents the application’s data and business logic. It is responsible for data storage, retrieval, and processing. In the context of MVVM, the Model has no direct interaction with the user interface and is designed to be independent of it.

View (V): The View is the user interface component of the application. It represents the visual elements that users interact with, such as buttons, text boxes, and graphics. In MVVM, the View’s role is to display data and handle user input but does not contain the application’s business logic.

ViewModel (VM): The ViewModel acts as an intermediary between the View and the Model. It holds the presentation logic and data necessary for the View to display. The ViewModel exposes properties and commands that the View binds to, allowing it to update the UI based on changes in the data (two-way data binding) and trigger actions in response to user interactions. The ViewModel is responsible for formatting data, handling user input validation, and other UI-related tasks. It also ensures that the Model remains isolated from the View, promoting a separation of concerns.

Pre-requisites:

Visual Studio 2022 17.3 or greater, with the .NET Multi-platform App UI workload installed. For more information, see Installation.

Visual Studio 2022 for Mac 17.4 or greater, with the .NET, .NET MAUI, Android, and iOS workloads installed. For more information, see Installation.

Knowledge in Model-View-ViewModel (MVVM)

If you are a new MAUI developer, you can use this link to create your first app.

Next, install Prism.Dryloc.Maui (We need to active pre-release option), Fody, and PropertyChanged.Fody

Configure MVVM

  1. Create a folder named ViewModels.
  2. Inside the new folder, add a new class BaseViewModel.
public abstract class BaseViewModel : BindableBase
{
public BaseViewModel(){ }
}

3. Inside the ViewModels folder, add a new folder named Pages

4. Inside the new folder, add a new class MainPageViewModel.

using System.Windows.Input;
using Mobile.Models;

namespace Mobile.ViewModels.Pages;

public class MainPageViewModel : BaseViewModel
{
public MyModel Model { get; set; }
public string Message { get; set; }
private int Counter { get; set; }

public ICommand TestCommand { get; set; }

public MainPageViewModel()
{
Message = "Click me.";
Model = new();
TestCommand = new DelegateCommand(Count);
}

private void Count()
{
Counter++;
Message = $"Clicked {Counter}";
}
}

5. Open the MainPage.xaml and update it

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Mobile.MainPage">

<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">

<Image
Source="{Binding Model.Image}"
HeightRequest="200"
HorizontalOptions="Center" />

<Label
Text="{Binding Model.Hello}"
FontSize="32"
HorizontalOptions="Center" />

<Label
Text="{Binding Model.Welcome}"
FontSize="18"
HorizontalOptions="Center" />

<Button
x:Name="CounterBtn"
Command="{Binding TestCommand}"
Text="{Binding Message}"
HorizontalOptions="Center" />

</VerticalStackLayout>
</ScrollView>

</ContentPage>

6. Open the MainPage.xaml.cs and remove the unnecessary code

namespace Mobile;

public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
}
}

7. In the root, add a new folder named Views

8. In the new folder, create a new folder named MainPage, then move the file MainPage.xaml into the newly created folder.

9. The MVVM pattern is almost complete, but it's not working. We need to modify the properties like this:

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace SDKSample
{
// This class implements INotifyPropertyChanged
// to support one-way and two-way bindings
// (such that the UI element updates when the source
// has been changed dynamically)
public class Person : INotifyPropertyChanged
{
private string name;
// Declare the event
public event PropertyChangedEventHandler PropertyChanged;

public Person()
{
}

public Person(string value)
{
this.name = value;
}

public string PersonName
{
get { return name; }
set
{
name = value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged();
}
}

// Create the OnPropertyChanged method to raise the event
// The calling member's name will be used as the parameter.
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
}

As you saw, it is a lot of code, that’s why we installed Fody and PropertyChanged.Fody

In the root, add a new file named FodyWeavers.xml

<Weavers>
<PropertyChanged />
</Weavers>

10. Open the MauiProgram.cs file, and update it

public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UsePrism((prism) =>
{
prism.RegisterTypes(container =>
{
container.RegisterForNavigation<MainPage, MainPageViewModel>();
})
.OnAppStart(app =>
{
app.NavigateAsync("MainPage");
});
})
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});

return builder.Build();
}

11. Finally, in the root, add the folder Models, and create the class MyModel.

public class MyModel
{
public string Hello { get; set; }
public string Image { get; set; }
public string Welcome { get; set; }

public MyModel()
{
Hello = "Hello, World!";
Image = "dotnet_bot.png";
Welcome = "Welcome to .NET Multi-platform App UI";
}
}

The configuration is completed. The project structure must be like this

Once the app is built and executed successfully, the FodyWeavers.xml file will be updated:

<?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<PropertyChanged />
</Weavers>

The mobile app works without code behind and using the MVVM pattern:

In summary, MVVM is a design pattern that enhances the organization and maintainability of UI-centric applications by dividing them into three distinct components: Model, View, and ViewModel, each with its own responsibilities and interactions, and we can leverage the .NET ecosystem to accelerate the development of our projects, while still adhering to good development practices and maintaining clean code.

Thank you for reading this. I am excited to see you soon.

--

--