背水一战 Windows 10 (103) - 通知(Toast): 基础, 按计划显示 toast 通知

时间:2023-03-09 03:41:46
背水一战 Windows 10 (103) - 通知(Toast): 基础, 按计划显示 toast 通知

[源码下载]

背水一战 Windows 10 (103) - 通知(Toast): 基础, 按计划显示 toast 通知

作者:webabcd

介绍
背水一战 Windows 10 之 通知(Toast)

  • 基础
  • 按计划显示 toast 通知

示例
1、本例用于演示当通过 toast 激活 app 时(前台方式激活),如何获取相关信息
Notification/Toast/Demo.xaml

<Page
x:Class="Windows10.Notification.Toast.Demo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows10.Notification.Toast"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Blue"> <TextBlock Name="lblMsg" VerticalAlignment="Center" HorizontalAlignment="Center" /> </Grid>
</Page>

Notification/Toast/Demo.xaml.cs

/*
* 本例用于演示当通过 toast 激活 app 时(前台方式激活),如何获取相关信息
*
*
* 在 App.xaml.cs 中 override void OnActivated(IActivatedEventArgs args),以获取相关的 toast 信息
*
* ToastNotificationActivatedEventArgs - 通过 toast 激活应用程序时(前台方式激活)的事件参数
* Argument - 由 toast 传递过来的参数
* UserInput - 由 toast 传递过来的输入框数据
* Kind - 此 app 被激活的类型(ActivationKind 枚举)
* 比如,如果是通过“打开文件”激活的话,则此值为 File
* PreviousExecutionState - 此 app 被激活前的状态(ApplicationExecutionState 枚举)
* 比如,如果此 app 被激活前就是运行状态的或,则此值为 Running
* SplashScreen - 获取此 app 的 SplashScreen 对象
* User - 获取激活了此 app 的 User 对象
*/ using System;
using Windows.ApplicationModel.Activation;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; namespace Windows10.Notification.Toast
{
public sealed partial class Demo : Page
{
private ToastNotificationActivatedEventArgs _toastArgs; public Demo()
{
this.InitializeComponent();
} protected override void OnNavigatedTo(NavigationEventArgs e)
{
// 获取 ToastNotificationActivatedEventArgs 对象(从 App.xaml.cs 传来的)
_toastArgs = e.Parameter as ToastNotificationActivatedEventArgs; if (_toastArgs != null)
{
// 获取 toast 的参数
lblMsg.Text = "argument: " + _toastArgs.Argument;
lblMsg.Text += Environment.NewLine; // 获取 toast 的 输入框数据
// UserInput 是一个 ValueSet 类型的数据,其继承自 IEnumerable 接口,可以 foreach(不能 for)
foreach (string key in _toastArgs.UserInput.Keys)
{
lblMsg.Text += $"key:{key}, value:{_toastArgs.UserInput[key]}";
lblMsg.Text += Environment.NewLine;
}
}
}
}
}

2、本例用于演示 toast 的基础
Notification/Toast/Basic.xaml

<Page
x:Class="Windows10.Notification.Toast.Basic"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows10.Notification.Toast"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent">
<StackPanel Margin="10 0 10 10"> <Button Name="buttonShowToast1" Content="显示 toast" Click="buttonShowToast1_Click" Margin="5" /> <Button Name="buttonShowToast2" Content="显示 toast(设置 toast 的过期时间)" Click="buttonShowToast2_Click" Margin="5" /> <Button Name="buttonShowToast3" Content="显示 toast(无 toast 通知 UI,仅放置于操作中心)" Click="buttonShowToast3_Click" Margin="5" /> </StackPanel>
</Grid>
</Page>

Notification/Toast/Basic.xaml.cs

/*
* 本例用于演示 toast 的基础
* 单击 toast 激活 app 后(前台方式激活),如何获取相关信息请参见 Demo.xaml.cs 中的代码
*
*
* ToastNotification - toast 通知
* Content - 一个 Windows.Data.Xml.Dom.XmlDocument 类型的对象(在构造函数中需要传递此对象),用于描述 toast 的 xml
* SuppressPopup - 默认值为 false
* false - 弹出 toast 通知,并放置于操作中心
* true - 不弹出 toast 通知,仅放置于操作中心
* ExpirationTime - 过期时间,超过这个时间就会从操作中心中移除
* ToastNotificationPriority - 优先级(Default 或 High)
* Group, Tag - 用于标识 toast 对象(前 16 个字符相同则认为相同)
* 同 group 且同 tag 则视为同一 toast,即新 toast 会更新旧 toast
* 系统会将所用未指定 group 的 toast 视为同 group
* 系统会将所用未指定 tag 的 toast 视为不同 tag
* Activated - 通过 toast 激活 app 时触发的事件
* Dismissed - 弹出的 toast 通知 UI 消失时触发的事件
* Failed - 弹出 toast 通知时失败
*
* ToastNotificationManager - toast 通知管理器
* CreateToastNotifier() - 创建 ToastNotifier 对象
* History - 获取 ToastNotificationHistory 对象
*
* ToastNotifier - toast 通知器
* Show(ToastNotification notification) - 弹出指定的 toast 通知
* Hide(ToastNotification notification) - 移除指定的 toast 通知
* Setting - 获取系统的通知设置
* Enabled - 通知可被显示
* DisabledForApplication - 用户禁用了此应用程序的通知
* DisabledForUser - 用户禁用了此计算机此账户的所有通知
* DisabledByGroupPolicy - 管理员通过组策略禁止了此计算机上的所有通知
* DisabledByManifest - 应用程序未在 Package.appxmanifest 中设置“应用图标”(其实你要是不设置的话编译都不会通过)
*
* ToastNotificationHistory - 本 app 的 toast 通知历史
* Clear() - 全部清除(从操作中心中移除)
* RemoveGroup() - 清除指定 group 的通知(从操作中心中移除)
* Remove() - 清除指定 tag 的通知或清除指定 tag 和 group 的通知(从操作中心中移除)
* GetHistory() - 获取历史数据,一个 ToastNotification 类型对象的集合(已被从操作中心中移除的是拿不到的)
*
*
*
* 注:本例是通过 xml 来构造 toast 的,另外也可以通过 NuGet 的 Microsoft.Toolkit.Uwp.Notifications 来构造 toast(其用 c# 对 xml 做了封装)
*/ using System;
using System.Diagnostics;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls; namespace Windows10.Notification.Toast
{
public sealed partial class Basic : Page
{
public Basic()
{
this.InitializeComponent();
} // 弹出 toast 通知
private void buttonShowToast1_Click(object sender, RoutedEventArgs e)
{
// 清除本 app 的之前的全部 toast 通知
// ToastNotificationManager.History.Clear(); // 用于描述 toast 通知的 xml 字符串
string toastXml = $@"
<toast activationType='foreground' launch='Notification-Toast-Basic-Arguments 1'>
<visual>
<binding template='ToastGeneric'>
<text>toast - title</text>
<text>toast - content 1 {DateTime.Now.ToString("mm:ss")}</text>
</binding>
</visual>
</toast>"; // 将 xml 字符串转换为 Windows.Data.Xml.Dom.XmlDocument 对象
XmlDocument toastDoc = new XmlDocument();
toastDoc.LoadXml(toastXml); // 实例化 ToastNotification 对象
ToastNotification toast = new ToastNotification(toastDoc);
// 系统会将所用未指定 group 的 toast 视为同 group
// 同 group 且同 tag 则视为同一 toast,即新 toast 会更新旧 toast
toast.Tag = ""; toast.Activated += Toast_Activated;
toast.Dismissed += Toast_Dismissed;
toast.Failed += Toast_Failed; // 弹出 toast 通知
ToastNotifier toastNotifier = ToastNotificationManager.CreateToastNotifier();
toastNotifier.Show(toast);
} // 弹出 toast 通知(设置 toast 的过期时间)
private void buttonShowToast2_Click(object sender, RoutedEventArgs e)
{
// 清除本 app 的之前的全部 toast 通知
// ToastNotificationManager.History.Clear(); string toastXml = $@"
<toast activationType='foreground' launch='Notification-Toast-Basic-Arguments 2'>
<visual>
<binding template='ToastGeneric'>
<text>toast - title</text>
<text>toast - content 2 {DateTime.Now.ToString("mm:ss")}</text>
</binding>
</visual>
</toast>"; XmlDocument toastDoc = new XmlDocument();
toastDoc.LoadXml(toastXml); ToastNotification toast = new ToastNotification(toastDoc);
DateTimeOffset expirationTime = DateTimeOffset.UtcNow.AddSeconds();
toast.ExpirationTime = expirationTime; // 30 秒后 toast 通知将从操作中心中移除 // 系统会将所用未指定 group 的 toast 视为同 group
// 系统会将所用未指定 tag 的 toast 视为不同 tag(此时虽然获取 tag 时其为空字符串,但是系统会认为其是一个随机值)
// 每次弹出此 toast 时都会被认为是一个全新的 toast
// toast.Tag = "2"; toast.Activated += Toast_Activated;
toast.Dismissed += Toast_Dismissed;
toast.Failed += Toast_Failed; ToastNotifier toastNotifier = ToastNotificationManager.CreateToastNotifier();
toastNotifier.Show(toast);
} // 弹出 toast 通知(无 toast 通知 UI,仅放置于操作中心)
private void buttonShowToast3_Click(object sender, RoutedEventArgs e)
{
// 清除本 app 的之前的全部 toast 通知
// ToastNotificationManager.History.Clear(); string toastXml = $@"
<toast activationType='foreground' launch='Notification-Toast-Basic-Arguments 3'>
<visual>
<binding template='ToastGeneric'>
<text>toast - title</text>
<text>toast - content 3 {DateTime.Now.ToString("mm:ss")}</text>
</binding>
</visual>
</toast>"; XmlDocument toastDoc = new XmlDocument();
toastDoc.LoadXml(toastXml); ToastNotification toast = new ToastNotification(toastDoc);
toast.SuppressPopup = true; // 不会弹出 toast 通知 UI,但是会放置于操作中心
toast.Tag = ""; toast.Activated += Toast_Activated;
toast.Dismissed += Toast_Dismissed;
toast.Failed += Toast_Failed; ToastNotifier toastNotifier = ToastNotificationManager.CreateToastNotifier();
toastNotifier.Show(toast);
} private void Toast_Activated(ToastNotification sender, object args)
{
Debug.WriteLine(sender.Tag + " Toast_Activated");
} private void Toast_Dismissed(ToastNotification sender, ToastDismissedEventArgs args)
{
Debug.WriteLine(sender.Tag + " Toast_Dismissed");
} private void Toast_Failed(ToastNotification sender, ToastFailedEventArgs args)
{
Debug.WriteLine(sender.Tag + " Toast_Failed");
}
}
}

3、演示如何按计划显示 toast 通知(在指定的时间显示指定的 toast 通知)
Notification/Toast/Schedule.xaml

<Page
x:Class="Windows10.Notification.Toast.Schedule"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Windows10.Notification.Toast"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Grid Background="Transparent">
<StackPanel Margin="10 0 10 10"> <!--显示当前 app 的全部 ScheduledToastNotification 对象列表-->
<ListBox Name="listBox" Width="800" Height="400" Margin="5" HorizontalAlignment="Left">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}" VerticalAlignment="Center" />
<TextBlock Text="{Binding Tag}" Margin="15 0 0 0" VerticalAlignment="Center" />
<HyperlinkButton Name="btnRemoveScheduledToast" Content="删除此 ScheduledToastNotification" Tag="{Binding Id}" Margin="15 0 0 0" Click="btnRemoveScheduledToast_Click" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox> <Button Name="btnAddScheduledToast" Content="添加指定的 ScheduledToastNotification 到计划列表中" Click="btnAddScheduledToast_Click" Margin="5" /> </StackPanel>
</Grid>
</Page>

Notification/Toast/Schedule.xaml.cs

/*
* 演示如何按计划显示 toast 通知(在指定的时间显示指定的 toast 通知)
*
* ScheduledToastNotification - 按计划显示 Toast 通知
* Content - Toast 的内容,XmlDocument 类型的数据,只读,其需要在构造函数中指定
* DeliveryTime - 显示 Toast 通知的时间,只读,其需要在构造函数中指定
* SnoozeInterval - 循环显示 Toast 通知的间隔时长(60 秒 - 60 分之间),只读,其需要在构造函数中指定(经测试,此逻辑无效)
* MaximumSnoozeCount - 循环的最大次数(1 - 5 次),只读,其需要在构造函数中指定(经测试,此逻辑无效)
* Id - ScheduledToastNotification 的标识
* Group, Tag - 用于标识 toast 对象(前 16 个字符相同则认为相同)
* 同 group 且同 tag 则视为同一 toast,即新 toast 会更新旧 toast
* 系统会将所用未指定 group 的 toast 视为同 group
* 系统会将所用未指定 tag 的 toast 视为不同 tag
* SuppressPopup - 默认值为 false
* false - 弹出 toast 通知,并放置于操作中心
* true - 不弹出 toast 通知,仅放置于操作中心
*
* ToastNotifier - toast 通知器
* AddToSchedule() - 将指定的 ScheduledToastNotification 对象添加到计划列表
* RemoveFromSchedule() - 从计划列表中移除指定的 ScheduledToastNotification 对象
* GetScheduledToastNotifications() - 获取当前 app 的全部 ScheduledToastNotification 对象列表
*/ using System;
using System.Collections.Generic;
using Windows.Data.Xml.Dom;
using Windows.UI.Notifications;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation; namespace Windows10.Notification.Toast
{
public sealed partial class Schedule : Page
{
public Schedule()
{
this.InitializeComponent();
} protected override void OnNavigatedTo(NavigationEventArgs e)
{
ShowScheduledToasts();
} // 添加指定的 ScheduledToastNotification 到计划列表中
private void btnAddScheduledToast_Click(object sender, RoutedEventArgs e)
{
string toastXml = $@"
<toast activationType='foreground' launch='Notification-Toast-Schedule-Arguments'>
<visual>
<binding template='ToastGeneric'>
<text>toast - title</text>
<text>toast - content {DateTime.Now.ToString("mm:ss")}</text>
</binding>
</visual>
</toast>"; // 将 xml 字符串转换为 Windows.Data.Xml.Dom.XmlDocument 对象
XmlDocument toastDoc = new XmlDocument();
toastDoc.LoadXml(toastXml); // 实例化 ScheduledToastNotification 对象(15 秒后显示此 Toast 通知,然后每隔 60 秒再显示一次 Toast,循环显示 5 次)
// 但是经测试,只会显示一次,无法循环显示,不知道为什么
// ScheduledToastNotification toastNotification = new ScheduledToastNotification(toastDoc, DateTime.Now.AddSeconds(15), TimeSpan.FromSeconds(60), 5); // 实例化 ScheduledToastNotification 对象(15 秒后显示此 Toast 通知)
ScheduledToastNotification toastNotification = new ScheduledToastNotification(toastDoc, DateTime.Now.AddSeconds()); toastNotification.Id = new Random().Next(, ).ToString();
toastNotification.Tag = toastDoc.GetElementsByTagName("text")[].InnerText; // 将指定的 ScheduledToastNotification 添加进计划列表
ToastNotifier toastNotifier = ToastNotificationManager.CreateToastNotifier();
toastNotifier.AddToSchedule(toastNotification); ShowScheduledToasts();
} // 删除指定的 ScheduledToastNotification 对象
private void btnRemoveScheduledToast_Click(object sender, RoutedEventArgs e)
{
string notificationId = (string)(sender as FrameworkElement).Tag; // 获取当前 app 的全部 ScheduledToastNotification 对象列表
ToastNotifier toastNotifier = ToastNotificationManager.CreateToastNotifier();
IReadOnlyList<ScheduledToastNotification> notifications = toastNotifier.GetScheduledToastNotifications(); int notificationCount = notifications.Count;
for (int i = ; i < notificationCount; i++)
{
if (notifications[i].Id == notificationId)
{
// 从计划列表中移除指定的 ScheduledToastNotification 对象
toastNotifier.RemoveFromSchedule(notifications[i]);
break;
}
} ShowScheduledToasts();
} // 显示当前 app 的全部 ScheduledToastNotification 列表
private void ShowScheduledToasts()
{
// 获取当前 app 的全部 ScheduledToastNotification 对象列表
ToastNotifier toastNotifier = ToastNotificationManager.CreateToastNotifier();
IReadOnlyList<ScheduledToastNotification> notifications = toastNotifier.GetScheduledToastNotifications(); listBox.ItemsSource = notifications;
}
}
}

OK
[源码下载]