Open a loading popup from MAUI viewmodel

NET8 MAUI Loading Indicator

In this new post, I show how to open a loading popup from ViewModel in MAUI. It is quite an easy implementation but it is working quite well.

Add CommunityToolkit.Maui

Create a new .NET MAUI project. Once that’s done, install the NuGet package CommunityToolkit.Maui into your project, as shown in the screenshot below:

.NET MAUI Community Toolkit in the NuGet Package Manager - Open a loading popup from MAUI viewmodel
.NET MAUI Community Toolkit in the NuGet Package Manager

Add the necessary initialization code in order to use the toolkit. Now we can move onto creating the actual popup.

Create the popup

The .NET MAUI Community Toolkit provides the Popup view, which you can use to create a custom UI that you can present to your users. We’ll use this and populate it with an ActivityIndicator, which will be our spinner.

Right-click your project and select Add New Item -> .NET MAUI -> .NET MAUI ContentPage (XAML). Name it LoadingPopup.xaml:

New .NET MAUI ContentPage (XAML) from the Add New Item dialog.
New .NET MAUI ContentPage (XAML) from the Add New Item dialog.

Replace the XAML content with this:

<toolkit:Popup
    x:Class="MyProject.LoadingPopup"
    xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:toolkit="http://schemas.microsoft.com/dotnet/2022/maui/toolkit">
    <VerticalStackLayout>
        <ActivityIndicator IsRunning="True" />
        <Label Text="Loading..." />
    </VerticalStackLayout>
</toolkit:Popup>

And update the code-behind (LoadingPopup.xaml.cs) to now inherit from Popup instead of ContentPage:

public partial class LoadingPopup : Popup
{
    ...
}

Open the popup

Since the project template already has a button in the MainPage file, we can update the Clicked event handler to open our popup. Go to the code-behind file of MainPage.xaml.cs and replace the content of the OnCounterClicked method:

var popup = new LoadingPopup();
this.ShowPopup(popup);

That’s it! That’s all you need to create your own spinner popup. If you want to programatically close the popup, you can call the Close()-method on the popup. Also, by default your popups can be dismissed by clicking outside of it. If you want to prevent this, you can set the CanBeDismissedByTappingOutsideOfPopup property of the Popup to false in your XAML.

Popup Service

Now, from the ViewModels, I can’t call the function ShowPopup or close an open popup. For this reason, I must create a service that helps me display or hide a popup from the ViewModel.

IPopupService

For this reason, the first step is to create an IPopupService interface

namespace MyProject.Interfaces
{
    public interface IPopupService
    {
        void Init(Page page);
        void ClosePopup(Popup popup);
        void ShowPopup(Popup popup);
    }
}

This is a very simple interface but it has everything I need to display and hide a popup.

PopupService

Now, the next step is to implement this service in the project. The code is following

public class PopupService : IPopupService
{
    Page page { get; set; }

    public void ClosePopup(Popup popup)
    {
        if (page == null)
            page = Application.Current?.MainPage ?? throw new NullReferenceException();
        popup.Close();
    }

    public void Init(Page page)
    {
        this.page = page;
    }

    public void ShowPopup(Popup popup)
    {
        if (page == null)
            page = Application.Current?.MainPage ?? throw new NullReferenceException();
        page.ShowPopup(popup);
    }
}

Register the service

After that, I have to register this service in the _MauiProgram.cs_. So, place this line in it:

builder.Services.AddTransient<Interfaces.IPopupService, Services.PopupService>();

As you can see, I added Interfaces because it could be confusion between IPopupService from the CommunityToolkit.Maui and my implementation.

Use the service

Now, on your page or in your view model, it is enough to inject this service in the constructor. For example:

Interfaces.IPopupService popupService;
Page page;

public MyViewModel(IPopupService popupService)
{
    this.popupService = popupService;
}

Open the popup

After that, in the view model, I can invoke the LoadingPage to popup like

var loading = new LoadingPopup();
popupService.ShowPopup(loading);

Close the popup

Now, to close the popup is enough to invoke the Close method like

popupService.ClosePopup(loading);

Wrap up

In this post, I show you how to open a loading popup from MAUI ViewModel using CommunityToolkit.Maui and an implemented custom service.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.