從 UWP 移轉至 WinUI 3 的應用程式通知
將應用程式通知程式代碼從 UWP 移轉至 WinUI 3 時,唯一的差異在於處理通知的啟用。 發送和管理應用程式通知保持完全相同。
注意
「快顯通知」一詞正取代為「應用程式通知」。 這些詞彙都是指 Windows 的相同功能,但隨著時間推移,我們將逐步淘汰文件中的「快顯通知」使用。
注意
針對發行前產品的部分相關資訊,在產品正式發行時可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
啟用差異
- Windows 應用程式 ADK (機器翻譯)
- Windows 社群工具組
類別 | UWP | WinUI 3 |
---|---|---|
前景啟用進入點 | App.xaml.cs 裡面的 OnActivated 方法被叫用 |
App.xaml.cs 裡面的 OnLaunched 方法被叫用。 |
背景啟用進入點 | 以背景工作個別處理 | 與前景啟動相同。 App.xaml.cs 裡面的 OnLaunched 方法被叫用。 使用 GetActivatedEventArgs 來判斷應用程式是否應該完全啟動,或只處理工作並結束。 |
視窗啟動 | 發生前景啟用時,系統會自動將視窗帶入前景 | 如有需要,您必須將視窗帶到前景 |
C# 應用程式的移轉
步驟 1:安裝 NuGet 連結庫
- Windows 應用程式 ADK (機器翻譯)
- Windows 社群工具組
針對 WinUI 3 應用程式,您可以使用 AppNotificationManager 類別處理通知的啟用。 此類別是由 Microsoft.WindowsAppSDK Nuget 套件提供,預設包含在 WinUI 3 Visual Studio 專案範本中。
第 2 步:更新清單
在您的 Package.appxmanifest 中,新增:
- xmlns:com 宣告
- xmlns:desktop 宣告
- 在 IgnorableNamespaces 屬性中,com 和 desktop
- windows.toastNotificationActivation 的 desktop:Extension,用於聲明您的 Toast 啟動器 CLSID (使用您選擇的新 GUID)。
- 僅限 MSIX:COM 啟動器的 com:Extension,使用步驟 #4 中的 GUID。 請務必包含
Arguments="----AppNotificationActivated:"
,以便您知道您的啟動是透過通知進行的
- Windows 應用程式 ADK (機器翻譯)
- Windows 社群工具組
<!--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:處理啟用
- Windows 應用程式 ADK (機器翻譯)
- Windows 社群工具組
在套用的啟動程式碼 (通常為 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 應用程式 ADK (機器翻譯)
- Windows 社群工具組
使用 Windows 應用程式 SDK,您仍然可以使用原始 xml 建立應用程式通知內容,但您也可以使用新的 AppNotificationsBuilder API 建立應用程式通知內容,該 API 取代了 Windows 社群工具包提供的 ToastContentBuilder 類別。 呼叫 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());