从 C# 应用发送本地 Toast 通知

toast 通知是用户当前未在应用内部时应用可构造并发送给用户的消息。

Toast 通知的屏幕截图

本快速入门指导你完成使用丰富内容和交互式操作创建、交付和显示 Windows 10 或 Windows 11 Toast 通知的步骤。 本快速入门使用本地通知,这是要实现的最简单通知。 所有类型的应用(WPF、UWP、WinForms、控制台)都可以发送通知!

重要

如果要编写 C++ 应用,请参阅 C++ UWPC++ WRL 文档。

步骤 1:安装 NuGet 包

在 Visual Studio 解决方案中,右键单击项目,单击“ 管理 NuGet 包...” ,然后搜索并安装 Microsoft.Toolkit.Uwp.Notifications NuGet 包 版本 7.0 或更高版本。

重要

仍使用 packages.config 的 .NET Framework 桌面应用必须迁移到 PackageReference,否则不会正确引用 Windows SDK。 在项目中,右键单击“引用”,然后单击“将 packages.config 迁移到 PackageReference”。

.NET Core 3.0 WPF 应用必须更新到 .NET Core 3.1,否则 API 将不存在。

.NET 应用必须使用 其中一个 Windows TPM,否则将缺少 Toast 发送和管理 API Show() 。 将 TFM net6.0-windows10.0.17763.0 设置为或更高版本。

代码示例将使用此包。 通过此包,无需使用 XML 即可创建 toast 通知,还允许桌面应用发送 toast。

步骤 2:发送 toast

在 Windows 10 和 Windows 11 中,你的 Toast 通知内容是使用自适应语言描述的,该语言允许你对通知的外观具有极大的灵活性。 有关详细信息,请参阅 toast 内容文档

我们将从基于文本的简单通知开始。 构造通知内容(使用通知库),然后显示通知! 请注意,命名空间为 Microsoft.Toolkit.Uwp.Notifications

简单文本通知
// Requires Microsoft.Toolkit.Uwp.Notifications NuGet package version 7.0 or greater
new ToastContentBuilder()
    .AddArgument("action", "viewConversation")
    .AddArgument("conversationId", 9813)
    .AddText("Andrew sent you a picture")
    .AddText("Check this out, The Enchantments in Washington!")
    .Show(); // Not seeing the Show() method? Make sure you have version 7.0, and if you're using .NET 6 (or later), then your TFM must be net6.0-windows10.0.17763.0 or greater

尝试运行此代码,应会看到通知出现!

步骤 3:处理激活

显示通知后,可能需要处理用户单击通知事件(这意味着在用户单击该通知后显示特定内容、一般情况下打开应用,还是在用户单击通知时执行操作)。

处理激活的步骤因 UWP 和打包和解压缩的桌面应用而异。

当用户单击通知(或具有前台激活的通知上的按钮)时,将调用应用的 App.xaml.cs OnActivated ,并返回添加的参数。

App.xaml.cs

protected override void OnActivated(IActivatedEventArgs e)
{
    // Handle notification activation
    if (e is ToastNotificationActivatedEventArgs toastActivationArgs)
    {
        // Obtain the arguments from the notification
        ToastArguments args = ToastArguments.Parse(toastActivationArgs.Argument);

        // Obtain any user input (text boxes, menu selections) from the notification
        ValueSet userInput = toastActivationArgs.UserInput;
 
        // TODO: Show the corresponding content
    }
}

重要

必须初始化框架并像 OnLaunched 代码一样激活窗口。 如果用户单击 Toast,即使应用已关闭且首次启动,也不会调用 OnLaunched。 我们通常建议将 OnLaunchedOnActivated 合并到自己的OnLaunchedOrActivated方法中,因为两者都需要进行相同的初始化。

步骤 4:处理卸载

无需执行任何操作! 卸载 UWP 应用时,会自动清理所有通知和其他任何相关资源。

添加图像

可以将丰富的内容添加到通知。 我们将添加内联图像和配置文件(应用徽标替代)图像。

注意

可以从应用的包、应用的本地存储或 Web 使用图像。 自 Fall Creators Update 起,正常连接上的 Web 图像的大小限制提升至 3 MB,按流量计费的连接上的限制提升至 1 MB。 在尚未运行 Fall Creators Update 的设备上,Web 图像的大小不得超过 200 KB。

重要

仅在清单中具有 Internet 功能的打包应用中支持 Http 映像。 未包装的应用不支持 Http 映像;必须将映像下载到本地应用数据中,并在本地引用它。

包含图像的 Toast
// Construct the content and show the toast!
new ToastContentBuilder()
    ...

    // Inline image
    .AddInlineImage(new Uri("https://picsum.photos/360/202?image=883"))

    // Profile (app logo override) image
    .AddAppLogoOverride(new Uri("ms-appdata:///local/Andrew.jpg"), ToastGenericAppLogoCrop.Circle)
    
    .Show();

添加按钮和输入

可以添加按钮和输入,使通知具有交互性。 按钮可以启动前台应用、协议或后台任务。 我们将添加一个回复文本框、一个“赞”按钮和一个打开图像的“查看”按钮。

包含输入和按钮的 Toast 通知的屏幕截图
int conversationId = 384928;

// Construct the content
new ToastContentBuilder()
    .AddArgument("conversationId", conversationId)
    ...

    // Text box for replying
    .AddInputTextBox("tbReply", placeHolderContent: "Type a response")

    // Buttons
    .AddButton(new ToastButton()
        .SetContent("Reply")
        .AddArgument("action", "reply")
        .SetBackgroundActivation())

    .AddButton(new ToastButton()
        .SetContent("Like")
        .AddArgument("action", "like")
        .SetBackgroundActivation())

    .AddButton(new ToastButton()
        .SetContent("View")
        .AddArgument("action", "viewImage")
        .AddArgument("imageUrl", image.ToString()))
    
    .Show();

前台按钮的激活处理方式与主 toast 正文相同(将调用 App.xaml.cs OnActivated)。

请注意,单击按钮时,添加到顶级 toast 的参数(例如对话 ID)也将返回,只要按钮使用如上所示的 AddArgument API(如果在按钮上自定义分配参数,则顶级参数不会包含在内)。

处理后台激活

在 Toast 上指定后台激活(或在 Toast 内的按钮上)时,将执行后台任务,而不是激活前台应用。

有关后台任务的详细信息,请参阅 使用后台任务支持应用。

如果要面向内部版本 14393 或更高版本,则可以使用进程内后台任务,从而大大简化操作。 请注意,进程内后台任务将无法在较旧版本的 Windows 上运行。 我们将在此代码示例中使用进程内后台任务。

const string taskName = "ToastBackgroundTask";

// If background task is already registered, do nothing
if (BackgroundTaskRegistration.AllTasks.Any(i => i.Value.Name.Equals(taskName)))
    return;

// Otherwise request access
BackgroundAccessStatus status = await BackgroundExecutionManager.RequestAccessAsync();

// Create the background task
BackgroundTaskBuilder builder = new BackgroundTaskBuilder()
{
    Name = taskName
};

// Assign the toast action trigger
builder.SetTrigger(new ToastNotificationActionTrigger());

// And register the task
BackgroundTaskRegistration registration = builder.Register();

然后,在 App.xaml.cs 中重写 OnBackgroundActivated 方法。 接下来可以检索预定义的参数和用户输入,类似于前台激活。

App.xaml.cs

protected override async void OnBackgroundActivated(BackgroundActivatedEventArgs args)
{
    var deferral = args.TaskInstance.GetDeferral();
 
    switch (args.TaskInstance.Task.Name)
    {
        case "ToastBackgroundTask":
            var details = args.TaskInstance.TriggerDetails as ToastNotificationActionTriggerDetail;
            if (details != null)
            {
                ToastArguments arguments = ToastArguments.Parse(details.Argument);
                var userInput = details.UserInput;

                // Perform tasks
            }
            break;
    }
 
    deferral.Complete();
}

设置过期时间

在 Windows 10 中,所有 Toast 通知在用户被消除或忽略后都会进入操作中心,以便用户可以在弹出窗口消失后查看通知。

但是,如果通知中的消息仅在一段时间内相关,则应在 Toast 通知上设置过期时间,以便用户看不到应用中的过时信息。 例如,如果促销仅有效 12 小时,请将到期时间设置为 12 小时。 在下面的代码中,我们将过期时间设置为 2 天。

注意

本地 Toast 通知的默认和最长过期时间为 3 天。

// Create toast content and show the toast!
new ToastContentBuilder()
    .AddText("Expires in 2 days...")
    .Show(toast =>
    {
        toast.ExpirationTime = DateTime.Now.AddDays(2);
    });

为 Toast 提供主键

如果要以编程方式删除或替换你发送的通知,则需要使用 Tag 属性((可选)为通知提供主键。 然后,可以在将来使用此主键删除或替换通知。

若要查看有关替换/删除已传递的 Toast 通知的更多详细信息,请参阅 快速入门:在操作中心(XAML)中管理 Toast 通知。

标记和组合用作复合主键。 组是更通用的标识符,可在其中分配“wallPosts”、“messages”、“friendRequests”等组。然后,Tag 应从组中唯一标识通知本身。 然后,通过使用泛型组,可以使用 RemoveGroup API 从该组中删除所有通知。

// Create toast content and show the toast!
new ToastContentBuilder()
    .AddText("New post on your wall!")
    .Show(toast =>
    {
        toast.Tag = "18365";
        toast.Group = "wallPosts";
    });

清除通知

应用负责删除和清除它们自己的通知。 启动应用后,我们不会自动清除通知。

仅当用户显式单击通知时,Windows 才会自动删除通知。

下面是消息应用应执行的操作的示例...

  1. 用户在对话中接收有关新消息的多个 Toast
  2. 用户点击其中一个 toast 以打开对话
  3. 应用将打开对话,然后清除该对话的所有 Toast(通过使用 该对话的应用提供的组上的 RemoveGroup
  4. 用户的操作中心现在正确反映通知状态,因为操作中心中没有留下的该会话的过时通知。

若要了解如何清除所有通知或删除特定通知,请参阅 快速入门:在操作中心(XAML)中管理 Toast 通知。

ToastNotificationManagerCompat.History.Clear();

资源