[WinUI 3] WindowのClosingイベントがやっと気軽に使えるようになった!

WinUI 3/Project Reunion 0.xではWindow.Closingイベントがなくて、Windowを閉じたときに未保存の注意などを実現するために、DllImportでWin32 APIを使わざるをえませんでした。
Project ReunionがWindows App SDK 1.0になってから、AppWindow APIを使うことで、簡単にClosingイベントを使えるようになりました!

目次

早速サンプルコード: Windowを閉じようとするとContentDialogを表示させる

必要なnamespace

using Microsoft.UI; using Microsoft.UI.Windowing;

AppWindow objectを取得する

private AppWindow GetCurrentAppWin() { //Windowのハンドルを取得する IntPtr hwnd = WinRT.Interop.WindowNative.GetWindowHandle(this); //hwndでWindowIdを取得する WindowId winId = Win32Interop.GetWindowIdFromWindow(hwnd); //WindowIdでAppWindow objectを取得して返す return AppWindow.GetFromWindowId(winId); }

AppWindow objectを利用してClosing Eventをハンドルする

AppWindow thisAppWin = GetCurrentAppWin(); if (thisAppWin != null) { thisAppWin.Closing += async (s, e) => { //Windowのcloseプロセスをキャンセルする e.Cancel = true; ContentDialog cd = new ContentDialog() { //XamlRootを指定しないとContentDialogが表示できない XamlRoot = this.Content.XamlRoot, PrimaryButtonText = "Yes", SecondaryButtonText = "No", Title = "注意", Content = "本当に終了しますか?", }; ContentDialogResult result = await cd.ShowAsync(); //注意:cdが表示されている間でも、再度Windowの閉じるボタンを押せば、Windowを閉じられます。 //これを防ぐには別途isClosing等のグローバル変数の導入が必要 if (result == ContentDialogResult.Primary) { App.Current.Exit(); //this.Close();でもOK、Closing() Eventを発生させない } }; }

AppWindow APIを理解する

Windowを閉じる際のClosingイベントを扱うには、Window objectそのもののEventではなく、代わりにAppWindowを使います。
AppWindowはWindowのハイレベルの抽象で、Windowを操作するための新たなAPIです。
難しい概念はさておき、簡単にいえば「WindowクラスにはClosingイベントがないので、WindowAppWindowオブジェクトを取得して、そのClosingイベントを実装すればいい」ということです。
また、AppWindowはWinUI 3にだけではなく、Win32、WPF、WinFormsにも使えます!
今はClosingイベントだけ使ってますが、今後は用途に合わせてほかのイベントやプロパティも使っていきたいと思います。

おまけ:AppWindowのTitleBarプロパティでタイトルバーの見た目を変えられる

AppWindowTitleBarプロパティにアクセスすれば、タイトルバーの背景色、文字色、最小化・最大化・閉じるボタンを押したときの背景色等、結構いろいろいじれます。
うまく組み合わせれば、結構おしゃれなWindowがデザインできるかもしれませんが、私はあまりそれをいじる派ではないので、とりあえず道具箱に眠らせておきます。

thisAppWin.TitleBar.ForegroundColor = Colors.Orange; thisAppWin.TitleBar.BackgroundColor = Colors.LightCyan; thisAppWin.TitleBar.ButtonBackgroundColor = Colors.BlueViolet; thisAppWin.TitleBar.ButtonHoverBackgroundColor = Colors.LightCoral;
WinUI 3 Window Closing Event


参考ページ

Microsoft Docs: Manage app windows

コメント

このブログの人気の投稿

C# WebView2.ExecuteScriptAsync()のいくつかの使い方とDebug方法

C# 外部ライブラリを使わずに半角→全角カタカナ変換

C# WebView2を通じてWebサーバーなしでJavaScriptからローカルファイルを読み書き