UWP から WinUI 3 への移行に関するアプリ通知
UWP から WinUI 3 にアプリ通知コードを移行する場合の唯一の違いは、通知のアクティブ化を処理することです。 アプリ通知の送信と管理はまったく同じです。
Note
"トースト通知" という用語は、"アプリ通知" に置き換えられます。 これらの用語はどちらも Windows の同じ機能を指していますが、時間の経過と共に、ドキュメントでの "トースト通知" の使用を段階的に廃止します。
Note
一部の情報はリリース前の製品に関する事項であり、正式版がリリースされるまでに大幅に変更される可能性があります。 Microsoft はここに示されている情報について、明示か黙示かを問わず、一切保証しません。
アクティブ化の違い
カテゴリ | UWP | WinUI 3 |
---|---|---|
フォアグラウンド アクティブ化エントリ ポイント | OnActivated App.xaml.cs 内のメソッドが呼び出されます |
OnLaunched App.xaml.cs 内のメソッドが呼び出されます。 |
バックグラウンド アクティブ化エントリ ポイント | バックグラウンド タスクとして個別に処理される | フォアグラウンド のアクティブ化と同じです。 OnLaunched App.xaml.cs 内のメソッドが呼び出されます。 GetActivatedEventArgs を使用して、アプリを完全に起動するか、タスクを処理して終了するかを判断します。 |
ウィンドウのアクティブ化 | フォアグラウンドのアクティブ化が発生すると、ウィンドウが自動的にフォアグラウンドに移動します | 必要に応じて、ウィンドウを前面に移動する必要があります |
C# アプリの移行
手順 1: NuGet ライブラリをインストールする
WinUI 3 アプリの場合は、 AppNotificationManager クラスを使用して通知のアクティブ化を処理します。 このクラスは、WinUI 3 Visual Studio プロジェクト テンプレートに既定で含まれている Microsoft.WindowsAppSDK Nuget パッケージによって提供されます。
手順 2: マニフェストを更新する
Package.appxmanifestに次を追加します。
- xmlns:com の 宣言
- xmlns:desktop の 宣言
- IgnorableNamespaces 属性では、com とデスクトップ
- トースト アクティベーター CLSID (任意の新しい GUID を使用) を宣言するための、windows.toastNotificationActivation の desktop:Extension
- MSIX のみ: COM アクティベーターの com:Extension (手順 4 の GUID を使用)。 通知から起動されたことがわかるように、必ず
Arguments="----AppNotificationActivated:"
を含めます
<!--Add these namespaces-->
<Package
...
xmlns:com="http://schemas.microsoft.com/appx/manifest/com/windows10"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
IgnorableNamespaces="... com desktop">
...
<Applications>
<Application>
...
<Extensions>
<!--Specify which CLSID to activate when app notification clicked-->
<desktop:Extension Category="windows.toastNotificationActivation">
<desktop:ToastNotificationActivation ToastActivatorCLSID="replaced-with-your-guid-C173E6ADF0C3" />
</desktop:Extension>
<!--Register COM CLSID LocalServer32 registry key-->
<com:Extension Category="windows.comServer">
<com:ComServer>
<com:ExeServer Executable="YourProject.exe" Arguments="----AppNotificationActivated:" DisplayName="App notification activator">
<com:Class Id="replaced-with-your-guid-C173E6ADF0C3" DisplayName="App notification activator"/>
</com:ExeServer>
</com:ComServer>
</com:Extension>
</Extensions>
</Application>
</Applications>
</Package>
手順 3: アクティブ化を処理する
アプリのスタートアップ コード (通常はApp.xaml.cs) で、次の手順に従ってコードを更新します。
- OnLaunched で、AppNotificationManager クラスの既定のインスタンスを取得します。
- AppNotificationManager.NotificationInvoked イベントに登録します。
- Microsoft.Windows.AppNotifications.AppNotificationManager.Register を呼び出して、通知イベントを受信するようにアプリを登録します。 NotificationInvoked ハンドラーを登録した後で、このメソッドを呼び出すことが重要です。
- ウィンドウの起動/アクティブ化コードを専用の
LaunchAndBringToForegroundIfNeeded
ヘルパー メソッドにリファクタリングして、複数の場所から呼び出すことができるようにします。 - 複数の場所から呼び出すことができるように、
HandleNotification
ヘルパー メソッドを作成します。 - AppInstance.GetActivatedEventArgsを呼び出し、返されたオブジェクトの AppActivationArguments.Kind プロパティの値ExtendedActivationKind.AppNotification を確認します。
- アクティブ化の種類が AppNotification でない場合はLaunchAndBringToForegroundIfNeeded ヘルパー メソッドを呼び出します。
- アクティブ化の種類が AppNotification の場合AppActivationArguments.Data プロパティを AppNotificationActivatedEventArgs にキャストし、
HandleNotification
ヘルパー メソッドに渡します。 - ApplicationManager.NotificationInvoked ハンドラーで、
HandleNotification
ヘルパー メソッドを呼び出します。 HandleNotification
ヘルパー メソッド内で、ウィンドウの表示や UI の更新など、UI 関連のコードを実行する前に、必ずアプリまたはウィンドウ ディスパッチャーにディスパッチしてください- アプリ通知のアクティブ化を処理した古い UWP
OnActivated
コードを新しいHandleNotification
ヘルパー メソッドに移行します。
移行されたApp.xaml.cs
protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)
{
m_window = new MainWindow();
// To ensure all Notification handling happens in this process instance, register for
// NotificationInvoked before calling Register(). Without this a new process will
// be launched to handle the notification.
AppNotificationManager notificationManager = AppNotificationManager.Default;
notificationManager.NotificationInvoked += NotificationManager_NotificationInvoked;
notificationManager.Register();
var activatedArgs = Microsoft.Windows.AppLifecycle.AppInstance.GetCurrent().GetActivatedEventArgs();
var activationKind = activatedArgs.Kind;
if (activationKind != ExtendedActivationKind.AppNotification)
{
LaunchAndBringToForegroundIfNeeded();
} else
{
HandleNotification((AppNotificationActivatedEventArgs)activatedArgs.Data);
}
}
private void LaunchAndBringToForegroundIfNeeded()
{
if (m_window == null)
{
m_window = new MainWindow();
m_window.Activate();
// Additionally we show using our helper, since if activated via a app notification, it doesn't
// activate the window correctly
WindowHelper.ShowWindow(m_window);
}
else
{
WindowHelper.ShowWindow(m_window);
}
}
private void NotificationManager_NotificationInvoked(AppNotificationManager sender, AppNotificationActivatedEventArgs args)
{
HandleNotification(args);
}
private void HandleNotification(AppNotificationActivatedEventArgs args)
{
// Use the dispatcher from the window if present, otherwise the app dispatcher
var dispatcherQueue = m_window?.DispatcherQueue ?? DispatcherQueue.GetForCurrentThread();
dispatcherQueue.TryEnqueue(async delegate
{
switch (args.Arguments["action"])
{
// Send a background message
case "sendMessage":
string message = args.UserInput["textBox"].ToString();
// TODO: Send it
// If the UI app isn't open
if (m_window == null)
{
// Close since we're done
Process.GetCurrentProcess().Kill();
}
break;
// View a message
case "viewMessage":
// Launch/bring window to foreground
LaunchAndBringToForegroundIfNeeded();
// TODO: Open the message
break;
}
});
}
private static class WindowHelper
{
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool SetForegroundWindow(IntPtr hWnd);
public static void ShowWindow(Window window)
{
// Bring the window to the foreground... first get the window handle...
var hwnd = WinRT.Interop.WindowNative.GetWindowHandle(window);
// Restore window if minimized... requires DLL import above
ShowWindow(hwnd, 0x00000009);
// And call SetForegroundWindow... requires DLL import above
SetForegroundWindow(hwnd);
}
}
アプリ通知コンテンツの構築
Windows アプリ SDKでは、未加工の xml を使用してアプリ通知コンテンツを作成できますが、Windows Community Toolkit によって提供される ToastContentBuilder クラスに代わる新しい AppNotificationsBuilder API を使用してアプリ通知コンテンツを作成することもできます。 AppNotificationManager.Show を呼び出して、アプリ通知を送信します。 Windows Community Toolkit と App SDK API の混在はお勧めしません。
using Microsoft.Windows.AppNotifications;
using Microsoft.Windows.AppNotifications.Builder;
...
var builder = new AppNotificationBuilder()
.AddText("Send a message.")
.AddTextBox("textBox")
.AddButton(new AppNotificationButton("Send")
.AddArgument("action", "sendMessage"));
var notificationManager = AppNotificationManager.Default;
notificationManager.Show(builder.BuildNotification());
関連トピック
Windows developer