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.
I did this in my code
PopupPage p = new PopupPage();
Application.Current.MainPage.ShowPopup(p);
await new TaskFactory().StartNew(() => { Thread.Sleep(5000); });
p.Close();
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With