Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to close the MauiCommunityToolkit Popup from Viewmodel

I want close a CommunityToolkit Popup in my Viewmodel. I tried using a WeakReferenceMessenger to receive a message like this:

        public mypopup()
    {
        InitializeComponent();
        WeakReferenceMessenger.Default.Register<string, string>(this, "popup", (r, d) =>
        {
            Debug.WriteLine(message: "received message");
            if (d == "close")
            {
                WeakReferenceMessenger.Default.Unregister<string>(this);
                MainThread.BeginInvokeOnMainThread(() => { this.Close(); });
            }
        });
    }

And somewhere else I use this to send a message

WeakReferenceMessenger.Default.Send<string, string>("close", "popup");

The 1st call works. And the SECOND time it will raise a System.NullReferenceException in MauiPopup.windows.cs Function void CleanUp() Target.ContextFlyout = null;

I also tried like this in message receive:

MainThread.BeginInvokeOnMainThread(() => { this.Close(); });

the same happens. I wonder if there is a solution or a better way to close popup from somewhere else without transferring the handle of popup.

like image 963
ss1969 Avatar asked Sep 12 '25 19:09

ss1969


2 Answers

I did this in my code

        PopupPage p = new PopupPage();
        Application.Current.MainPage.ShowPopup(p);
        await new TaskFactory().StartNew(() => { Thread.Sleep(5000); });
        p.Close();
like image 176
Orion77 Avatar answered Sep 14 '25 11:09

Orion77


In MVVM, the View would subscribe to the events of the ViewModel The viewModel would look like the following:

public delegate Task CloseHandler<T> (T result);

public class TheViewModel : ObservableObject
{
    public event CloseHandler<bool> OnClose;
    public TheViewModel()
    {
        CloseCommand = new RelayCommand<bool>(async result => await OnClose?.Invoke(result));
    }

    public ICommand CloseCommand { get; set; }        
}

And the codebehind of the view would look like this:

public partial class ThePopup : Popup
{
    public ThePopup(TheViewModel vm)
    {
        InitializeComponent();
        BindingContext = vm;
        vm.OnClose += async result => await CloseAsync(result, CancellationToken.None);
    }
}

You can find a simple example here

enter image description here

like image 24
adPartage Avatar answered Sep 14 '25 12:09

adPartage