When our UWP Application deal with user data in it, e.g. like drawings or documents, we usually want to make sure user won't close the App by accident and lose their work. Just like what you see in a Office application, it will ask you if you want to save your document before close the App.

For a long time, UWP could not do that in a normal way. Because it is not a general public API and it is still not well documented today. But there are some UWP Apps with this capibility like Microsoft's own "Paint 3D" App:

I did some research today and finally find a way to do this. Let me share with you.

1. Add Restricted API Capability


Open your Package.appxmanifest file.

Add a namespace into Package node:

xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"

In order to create App Package without error, we also need to ignore the rescap namespace by adding it into IgnorableNamespaces property in the Package node:

IgnorableNamespaces="uap mp rescap genTemplate"

The Package node will look like this:

<Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" 
         xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" 
         xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" 
 
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
         IgnorableNamespaces="uap mp rescap">

Then, in Capabilities node, add:

<rescap:Capability Name="confirmAppClose"/>

The Capabilities will look like this:

<Capabilities>
...
  <rescap:Capability Name="confirmAppClose"/>
...
</Capabilities>

2. Handling Close App Action


The close app action can now be handled by a preview API:

Windows.UI.Core.Preview.SystemNavigationManagerPreview.GetForCurrentView().CloseRequested

For example, in your code, like MainPage.xaml.cs, you can now use this API to detect if the user clicked "X" button and pop up the dialog like this:

public MainPage()
{
    this.InitializeComponent();

    Windows.UI.Core.Preview.SystemNavigationManagerPreview.GetForCurrentView().CloseRequested +=
        async (sender, args) =>
        {
            args.Handled = true;

            var result = await SaveConfirm.ShowAsync();
            if (result == ContentDialogResult.Primary)
            {
                // Save work;
            }
            else
            {
                App.Current.Exit();    
            }
        };
}

One thing to notice is that, args.Handeled must be set to true, or your App will still close on clicking the "X" button.