Search code examples
.netmauimaui-windows

How does the MAUI Windows App pop up a second-confirmation dialog while close window?


I'm making an application run on Windows PC by dotnet MAUI, and now I want to pop up a dialog when the user clicked the "X" button.

Like this: enter image description here

When user clicked the "X" (Close Button), the application needs to pop up a dialog asking if the user really wants to close the app. On Stackoverflow I found solutions for Android and MacOS, but not for Windows. I tried to use the code below, but it can only do some logic while closing the app, and it doesn't prevent the application from closing.

 public partial class App : Application
 {
     public App()
     {
         InitializeComponent();
     }

     protected override Window CreateWindow(IActivationState? activationState)
     {
         var window = new Window(new AppShell())
         {
             MinimumHeight = 520,
             MinimumWidth = 850
         };

         window.Destroying += (sender, args) =>
         {
             Debug.WriteLine("The window is destroing!");
         };

         return window;
     }
}

At the same time, registering an async method for the Destroying event is also invalid because it does not wait for the async method to finish executing. Instead, it will be interrupted directly because the application is closed.

Like the code below, there won't be any dialog poped up, and I can only found the log "Before await".

protected override Window CreateWindow(IActivationState? activationState)
{
    var window = new Window(new AppShell())
    {
        MinimumHeight = 520,
        MinimumWidth = 850
    };

    window.Destroying += async (sender, args) =>
    {
        Debug.WriteLine("Before await");
        await Application.Current.MainPage.DisplayAlert("xx", "xxx", "y", "n");
        Debug.WriteLine("After await");
    };

    return window;
}

Solution

  • You can try to use the AppWindow.Closing Event to do that. Please put the following code into the App.cs's constructor.

    #if WINDOWS
    using Microsoft.UI.Windowing;
    #endif
    .......
            public App()
            {
                InitializeComponent();
                Microsoft.Maui.Handlers.WindowHandler.Mapper.AppendToMapping(nameof(IWindow), (handler, view) =>
                {
    #if WINDOWS
                    var nativeWindow = handler.PlatformView;
                    var appWindow = nativeWindow.GetAppWindow();
                    if (appWindow is not null)
                    {
                        appWindow.Closing += async (sender, args) =>
                        {
                            args.Cancel = true;
                            if (App.Current.MainPage != null)
                            {
                                bool value = await App.Current.MainPage.DisplayAlert("xxx", "xx", "yes", "no");
                                if(value == true)
                                {
                                    nativeWindow.Close();
                                }
                            }
                        };
                    }
    #endif               
                });
                MainPage = new AppShell();
            }