かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

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

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