かずきのBlog@hatena

すきな言語は C# + XAML の組み合わせ。Azure Functions も好き。最近は Go 言語勉強中。日本マイクロソフトで働いていますが、ここに書いていることは個人的なメモなので会社の公式見解ではありません。

UWP でアプリを閉じるときに確認画面を出す方法

これずっと出来ないと思ってたのですが de:code 用に色々見てたら出来るっちゃぁ出来るようになってるのを見つけました。 下記の権限のサイトをみてみると confirmAppClose っていうのがある!?

docs.microsoft.com

試してみよう

confirmAppClose の機能を Package.appxmanifest に追加します。

<!--
この名前空間を追加して
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces に以下のように rescap も追加
IgnorableNamespaces="uap mp rescap"
-->

<Capabilities>
  <Capability Name="internetClient" />
  <!-- これを追加 -->
  <rescap:Capability Name="confirmAppClose" />
</Capabilities>

そして、SystemNavigationManagerPreview クラスを使って頑張る感じですね。

using System;
using Windows.UI.Core.Preview;
using Windows.UI.Popups;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace ConfirmCloseApp
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            SystemNavigationManagerPreview.GetForCurrentView().CloseRequested += MainPage_CloseRequested;
        }

        private async void MainPage_CloseRequested(object sender, SystemNavigationCloseRequestedPreviewEventArgs e)
        {
            e.Handled = true;
            var d = new MessageDialog("閉じてもよろしいですか?");
            var okCommand = new UICommand("OK");
            d.Commands.Add(okCommand);
            var cancelCommand = new UICommand("Cancel");
            d.Commands.Add(cancelCommand);
            var r = await d.ShowAsync();
            if (r == okCommand)
            {
                Application.Current.Exit();
            }
        }
    }
}

こうすることで閉じる前に確認を挟むことが出来ます。ただ、このイベントは必ず発生するものではなくタブレットモードで上からしたにスワイプしたりしたときには発生しないとかいくつか発生しないケースがあるみたいですね

docs.microsoft.com

なので、この機能を使うにしてもサスペンドのタイミングでユーザーの作業中の未保存のデータがある場合には保存してあげて、そして再度アプリが立ち上げられたタイミングで復元してあげるのが良さそうです。