infinitesimal
infinitesimal

Reputation: 440

Popup service, show popup in Maui

How to use PopupService to show popup in ViewModel?


I have ViewModel with:

[RelayCommand]
private async Task ShowPopupAsync(object sender)
{
     var popup = popUpService.GetPopup(sender);
     popupService.ShowPopup(popup);
}

PopUpService:

public Popup GetPopup(object sender)
{
    var button = sender as ImageButton;
    var popup = new CustomPopup
    {
        Anchor = button
    };

    return popup;
}

And I have error in line popupService.ShowPopup(popup);:

System.Collections.Generic.KeyNotFoundException: 'The given key 'CommunityToolkit.Maui.Views.Popup' was not present in the dictionary.'

When I use Shell.Current.ShowPopup(popup); everything works but I don't want to use Shell in my ViewModel.

Upvotes: 1

Views: 1221

Answers (2)

Jessie Zhang -MSFT
Jessie Zhang -MSFT

Reputation: 13879

CommunityToolkit.Maui has a built-in interface that provides logic for popups.

We can first create a Popup view:

<?xml version="1.0" encoding="utf-8" ?>
<mct:Popup xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
           xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
           xmlns:mct="clr-namespace:CommunityToolkit.Maui.Views;assembly=CommunityToolkit.Maui"
           x:Class="YourApp.Views.PopupView"
           CanBeDismissedByTappingOutsideOfPopup="False"
           Size="300, 300">
    <VerticalStackLayout BackgroundColor="White">
        <Label 
            Text="Welcome to .NET MAUI!"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />   
        <Button Text="Close" />
    </VerticalStackLayout>
</mct:Popup>

PopupView.xaml.cs

using CommunityToolkit.Maui.Views;

namespace YourApp.Views.Popups;

public partial class PopupView : Popup
{
    public PopupView(PopupViewModel vm)
    {
        InitializeComponent();
        BindingContext = vm;
    }
}

Using from other VM:

 public OtherViewModel(IPopupService popupService)
 {
     _popupService = popupService;
 }

 public async Task ShowPopup()
 {
     await _popupService.ShowPopupAsync<PopupViewModel>();
 }

Note:

Remember to register your popup in MauiProgram.cs

builder.Services.AddTransientPopup<PopupView,PopupViewModel>();

Upvotes: 2

H.A.H.
H.A.H.

Reputation: 3907

There is built-in popup service - the default navigation.

https://learn.microsoft.com/en-us/dotnet/maui/user-interface/pages/navigationpage?view=net-maui-8.0#perform-modal-navigation

Make new ContentPage, and in the xaml:

  1. Set background to something semi-transparent: BackgroundColor="#99000000"
  2. Add Grid with Border and set nice round corners: StrokeShape="{RoundRectangle CornerRadius=20}"
  3. Put another container inside the border and then everything in it.

You can call it from anywhere, as simple as:

PushModalAsync(new WaitPage(), false);

False means I do not like animation, you may actually like it. Also no one is telling you not to use DI. Do not pay attention to my manual construction.

And you can close it from anywhere with:

PopModalAsync(false);

If you develop for mobile, you need to consider hardware back button press for android, and override it in your popup page:

protected override bool OnBackButtonPressed()
{
    return true; //consumes it
}

No extra libs needed. Plain MAUI.

Upvotes: 3

Related Questions