Using ViewModels MAUI: Simplifying Cross-Platform App Development Pt. 1 - Setting up your viewmodels

James Timberlake · Wed Oct 04 2023

dotnet_maui_mvm.png

In the ever-evolving landscape of cross-platform app development, .NET MAUI (Multi-platform App UI) has emerged as a powerful framework that allows developers to build native apps for Android, iOS, macOS, and Windows using a single codebase. One of the key concepts in .NET MAUI is the use of the MVVM framework to manage the logic and data binding in your app. In this blog post, we'll explore how to tie ViewModels to views in .NET MAUI, simplifying the development process and enhancing the maintainability of your code.

In this 2 part discussion, we’ll go over how to create a viewmodel, tie it to a viewmodel to bind to elements in the view, and how to use this with the new navigation and dependency injection elements that come with Maui. 

In this entry, we’re focusing on the basic setup of a viewmodel and binding it to a view.

What are ViewModels?

Before we dive into the details of connecting ViewModels with views, let's briefly understand what ViewModels are and why they are important in .NET MAUI.

ViewModels are classes that encapsulate the data, business logic, and state management of a specific view or page in your app. They serve as the intermediary between the user interface (UI) and the underlying data, abstracting the UI logic from the view, and enabling better separation of concerns. By using ViewModels, you can create a clean and maintainable architecture for your app.

Benefits of Using ViewModels/MVVM Framework

  • Separation of Concerns: ViewModels allow you to separate the presentation logic (UI) from the business logic. This separation makes your code easier to understand, test, and maintain.
  • Reusability: Since ViewModels are not tied to specific views, you can reuse them across multiple views or pages, regardless of the platform. This promotes code reuse and reduces duplication.
  • Testability: ViewModels are easy to unit test because they contain the view’s core logic. You can write unit tests to validate the behavior of your view models independently of the UI.
  • Data Binding: .NET MAUI leverages data binding to automatically update the UI when the underlying data in a BaseViewModel changes. This simplifies the process of keeping your UI in sync with your data.

Now that we understand the importance of BaseViewModels, let's explore how to connect them to views in .NET MAUI.

Tying BaseViewModels to Views

Create a ViewModel:
Start by creating a ViewModel class for your view or page. This class should inherit from ObservableObject, which is part of the .NET MAUI framework. Here's an example of a simple ViewModel:

 

using Microsoft.Maui.Controls;


 

public class MyPageViewModelObservableObject
{
    private string _message;

    public string Message
    {
        get => _message;
        set => SetProperty(ref _message, value);
    }

 

ObservableObject is a new component used in Maui that wraps the implementation of INotifyPropertychanged in a convenient way.

Creating the View:
Next, create the view (page) that corresponds to your ViewModel. You can use XAML or C# for this purpose. Ensure that the view has a corresponding code-behind file. 

 

<?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"
            xmlns:local="clr-namespace:YourAppNamespace"
            x:Class="YourAppNamespace.MyPage"
            x:DataType="YourAppNamespace.MyPageViewModel">>
    <StackLayout>
        <Label Text="{Binding Message}" />
        <!-- Additional UI elements go here -->
    </StackLayout>

</ContentPag

If you notice while instantiating the ContentPage,  you’ll see we’re setting a value for an attribute called x:DataType. While you don’t necessarily need x:DataType, this allows for better performance using compile-time binding.

 

When MAUI evaluates the binding expression in XAML regarding BindingContext, the binding is validated at runtime and is not cost efficient. This can lead to slower app performance and increase in debug time towards view binding. Using the x:DataType , the binding expressions given the VisualElement are evaluated at compile-time. Any errors from bindings that would crash at runtime are now presented as build errors. Use this whenever you can!

 

Connect the View to the ViewModel:
In your view's code-behind (C# file), set the Binding Context to an instance of your ViewModel. This connects the view to the view model and enables data binding.

 

public partial class MyPageContentPage
{
    public MyPage(MyPageViewModel viewModel)
    {
        InitializeComponent();
        BindingContext = viewModel;
    }

 

Data Binding in XAML:
In your XAML file, you can now use data binding to display and manipulate data from the ViewModel. In the example above, we bound the Text property of a Label to the Message property of the view model. Any changes to the Message property will automatically update the UI.

 

iPhone Data Binding Example

 

ViewModel Logic:
Implement the desired business logic and data manipulation in your BaseViewModel class. When data changes, use the SetProperty method provided by ObservableObject to notify the view of changes and trigger updates.

Connecting ViewModel to a C# Content Page

If you prefer to create your view entirely in C# without XAML, you can do so. Here's how you can connect your BaseViewModel to a C# Content Page:

Create the C# Content Page:
Create a new C# class that inherits from ContentPage to represent your view. In the constructor, set the Binding Context to an instance of your BaseViewModel.

using Microsoft.Maui.Controls;

public class MyPageContentPage
{
    public MyPage(MyPageViewModel viewModel)
    {
        BindingContext = viewModel;
        
        // Build your UI elements here using C#
        var label = new Label();
        label.SetBinding(Label.TextProperty, "Hello World");
        
        // Add UI elements to the page's content
        Content = new StackLayout
        {
            Children = { label }
        };
    }
}

 

With this approach, you're defining your entire view and its UI elements in C# code while still connecting it to your BaseViewModel for data binding and logic.

Conclusion

Tying ViewModels to views in .NET MAUI is a fundamental step in creating well-structured and maintainable cross-platform apps. By using ViewModels, you can separate concerns, enhance code reusability, and simplify testing, all while taking advantage of data binding to keep your UI responsive to changes in your data.

.NET MAUI empowers developers to create native apps for multiple platforms with ease, and incorporating BaseViewModels into your development process is a key practice for building robust and maintainable apps. Whether you're a seasoned .NET developer or new to the framework, embracing this pattern will undoubtedly streamline your app development journey.


 

james_timberlake.png

James Timberlake

James is a solutions leader and mobile enthusiast, especially in regards to hybrid languages like .net Maui, React Native, and Flutter.

Take the Next Step in Your Digital Transformation

Concentrate on your brand, business, or project while we handle the software development.

Get in touch with Kava Up to learn more!

Contact Us

Contact Us

Required fields are marked with an asterisk*