[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を表示させる
- AppWindow APIを理解する
- おまけ:AppWindowのTitleBarプロパティでタイトルバーの見た目を変えられる
- 参考ページ
早速サンプルコード: 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
イベントがないので、Window
のAppWindow
オブジェクトを取得して、そのClosing
イベントを実装すればいい」ということです。
また、AppWindowはWinUI 3にだけではなく、Win32、WPF、WinFormsにも使えます!
今はClosing
イベントだけ使ってますが、今後は用途に合わせてほかのイベントやプロパティも使っていきたいと思います。
おまけ:AppWindowのTitleBarプロパティでタイトルバーの見た目を変えられる
AppWindow
のTitleBar
プロパティにアクセスすれば、タイトルバーの背景色、文字色、最小化・最大化・閉じるボタンを押したときの背景色等、結構いろいろいじれます。
うまく組み合わせれば、結構おしゃれなWindowがデザインできるかもしれませんが、私はあまりそれをいじる派ではないので、とりあえず道具箱に眠らせておきます。
thisAppWin.TitleBar.ForegroundColor = Colors.Orange;
thisAppWin.TitleBar.BackgroundColor = Colors.LightCyan;
thisAppWin.TitleBar.ButtonBackgroundColor = Colors.BlueViolet;
thisAppWin.TitleBar.ButtonHoverBackgroundColor = Colors.LightCoral;
コメント
コメントを投稿
個人情報を記入しないようご注意ください