Toast通知管理器
Toast Notification Manager组件显示Toast通知——一个Windows 10版本的警报窗口。
提示:
- Toast通知只能在Windows 8.0或更高版本下显示,对于较旧的Windows版本,请使用警报窗口。
- Windows只对那些固定在“开始”菜单上的应用程序显示toast通知。
- 如果用户禁用了通知(特定于应用程序的通知或所有通知),Toast通知管理器将无法显示通知。
- 该组件使用系统的COM对象将通知数据传递给Windows通知平台,Windows根据这些数据显示通知。如果您的应用程序或用户没有访问Windows通知平台的权限,则不会弹出通知。
应用程序可以同时显示多个通知,也可以一次多次显示一个通知。ToastNotification对象有9个内容模板,可以播放声音。
创建通知
1.将ToastNotificationManager组件从Visual Studio的工具箱中拖放到表单上。
3.调用管理器的智能标记并单击Edit Notifications…链接。
4.在集合编辑器对话框中,单击 Add 添加通知,这会创建新的ToastNotification对象,并将它们添加到管理器的ToastNotificationsManager.Notifications集合中,您可以自定义属性网格中的通知设置。
- ToastNotification.Body和IToastNotificationProperties.Body2 ——两个常规文本字符串,它们是主要的通知文本。Body2行可以被禁用,这取决于所选择的模板(见下文)。
- ToastNotification.Duration——获取或设置如果用户不关闭通知,通知的可见时间。
- ToastNotification.Header——在通知标题中显示的粗体文本字符串,标题字符串可以占一到两行,这取决于通知模板。
- ToastNotification.ID ——一个只读属性且存储唯一通知的ID。
- ToastNotification.Image ——获得或设置通知形象。
- ToastNotification.Sound ——允许您指定一个声音通知。
- ToastNotification.Template——获取或设置通知模板,下表说明了不同的通知类型。
模板 | 描述 |
---|---|
Text01 |
IToastNotificationProperties.Body字符串,最多占用三行。 |
Text02 |
第一行是粗体的IToastNotificationProperties.Header文本字符串,第二行和第三行是IToastNotificationProperties.Body的换行文本字符串。 |
Text03 |
字符串的粗体IToastNotificationProperties.Header文本占据第一行和第二行,IToastNotificationProperties.Body文本在第三行。 |
Text04 |
粗体IToastNotificationProperties.Header文本在第一行,IToastNotificationProperties.Body字符串在第二行,IToastNotificationProperties.Body2字符串在第三行。 |
ImageAndText01 |
Text01模板和图像 |
ImageAndText02 |
Text02模板和图像 |
ImageAndText03 |
Text03模板和图像 |
ImageAndText04 |
Text04模板和图像 |
Generic |
Windows 10风格的通知,使用以下属性指定通知内容:
|
5.要显示特定的通知,请使用ToastNotificationsManager.ShowNotification方法。
C#:
toastNotificationsManager1.ShowNotification(toastNotificationsManager1.Notifications[3]); //or toastNotificationsManager1.ShowNotification("3b7fcd8b-a1e0-4ff5-83ce-023cdf6be24b");
VB.NET:
toastNotificationsManager1.ShowNotification(toastNotificationsManager1.Notifications(3)) 'or toastNotificationsManager1.ShowNotification("3b7fcd8b-a1e0-4ff5-83ce-023cdf6be24b")
管理终端用户交互
根据用户的操作,会发生以下事件:
- ToastNotificationsManager. Activated ——如果最终用户单击此通知,则发生,处理此事件来检查单击了哪个通知,并根据结果执行操作。下面的代码演示了一个示例。
C#:
private void toastNotificationsManager1_Activated(object sender, DevExpress.XtraBars.ToastNotifications.ToastNotificationEventArgs e) { switch (e.NotificationID.ToString()) { case "3b7fcd8b-a1e0-4ff5-83ce-023cdf6be24b": MessageBox.Show("Notification #1 Clicked"); break; case "66501f90-ac6b-440d-bf73-483c5ab22143": MessageBox.Show("Notification #2 Clicked"); break; } }
VB.NET:
Private Sub toastNotificationsManager1_Activated(sender As Object, e As DevExpress.XtraBars.ToastNotifications.ToastNotificationEventArgs) Select Case (e.NotificationID.ToString() Case "3b7fcd8b-a1e0-4ff5-83ce-023cdf6be24b" MessageBox.Show("Notification #1 Clicked") Exit Select Case "66501f90-ac6b-440d-bf73-483c5ab22143" MessageBox.Show("Notification #2 Clicked") Exit Select End Select End Sub
- ToastNotificationsManager.UserCancelled——在最终用户关闭通知时发生。
- ToastNotificationsManager.TimedOut——在最终用户没有响应通知并且在一段时间后隐藏通知时发生,下面的代码重新发送超时通知。
C#:
private void toastNotificationsManager1_TimedOut(object sender, DevExpress.XtraBars.ToastNotifications.ToastNotificationEventArgs e) { toastNotificationsManager1.ShowNotification(e.NotificationID); }
VB.NET:
Private Sub toastNotificationsManager1_TimedOut(sender As Object, e As DevExpress.XtraBars.ToastNotifications.ToastNotificationEventArgs) toastNotificationsManager1.ShowNotification(e.NotificationID) End Sub
- ToastNotificationsManager.Hidden ——当toast通知被ToastNotificationsManager.HideNotification或ToastNotificationsManager.HideNotification方法隐藏时发生。
- ToastNotificationsManager.Dropped—当通知因最终用户的系统设置而取消时触发。
使用“Generic”模板自定义通知
下面的XML标记是toast通知的内容布局示例:
XML:
<toast displayTimestamp="2018-01-05T13:35:00Z"> <visual> <binding template="ToastGeneric"> <text id="1">Header Text</text> <text id="2">Body Text</text> <text id="3">Body 2 Text</text> <text placement="attribution">Attribution Text</text> <image src="file:///C:/Users/John.Doe/AppData/Local/Temp/tmpBC2C.tmp4e9214ef-f478-4cea-972a-3fdd6c3acac0.png" placement="appLogoOverride" hint-crop="circle" /> <image src="file:///C:/Users/John.Doe/AppData/Local/Temp/tmpBC2D.tmpeb4a5986-fd2a-4d7d-a69d-a78f0061d754.png" placement="hero" /> <image src="file:///C:/Users/John.Doe/AppData/Local/Temp/tmpBC1B.tmp43598461-7e59-4600-a95c-88edbc57b2ec.png" /> </binding> </visual> </toast>
您可以处理 ToastNotificationsManager.UpdateToastContent事件来使用System.XML命名空间的API修改此模板。例如,下面的代码将具有两个子组的组添加到通知布局,每个子组显示两个额外的文本块,垂直排列。
C#:
using System.Xml; public Form1() { InitializeComponent(); //. . . toastNotificationsManager1.UpdateToastContent += ToastNotificationsManager1_UpdateToastContent; } private void ToastNotificationsManager1_UpdateToastContent(object sender, DevExpress.XtraBars.ToastNotifications.UpdateToastContentEventArgs e) { XmlDocument content = e.ToastContent; XmlNode bindingNode = content.GetElementsByTagName("binding").FirstOrDefault(); XmlElement group = content.CreateElement("group"); bindingNode.AppendChild(group); XmlElement subGroup = content.CreateElement("subgroup"); group.AppendChild(subGroup); XmlElement text = content.CreateElement("text"); subGroup.AppendChild(text); text.SetAttribute("hint-style", "base"); text.InnerText = "subgroup1"; text = content.CreateElement("text"); subGroup.AppendChild(text); text.SetAttribute("hint-style", "captionSubtle"); text.InnerText = "captionSubtle"; subGroup = content.CreateElement("subgroup"); group.AppendChild(subGroup); text = content.CreateElement("text"); subGroup.AppendChild(text); text.SetAttribute("hint-style", "captionSubtle"); text.SetAttribute("hint-align", "right"); text.InnerText = "subgroup2"; text = content.CreateElement("text"); subGroup.AppendChild(text); text.SetAttribute("hint-style", "captionSubtle"); text.SetAttribute("hint-align", "right"); text.InnerText = "captionSubtle"; // Save the toast markup as an XML file for debugging purposes content.Save(@"D:\Toast.xml"); }
VB.NET:
Imports System.Xml Public Sub New() InitializeComponent() '. . . AddHandler toastNotificationsManager1.UpdateToastContent, AddressOf ToastNotificationsManager1_UpdateToastContent End Sub Private Sub ToastNotificationsManager1_UpdateToastContent(ByVal sender As Object, ByVal e As DevExpress.XtraBars.ToastNotifications.UpdateToastContentEventArgs) Dim content As XmlDocument = e.ToastContent Dim bindingNode As XmlNode = content.GetElementsByTagName("binding").FirstOrDefault() Dim group As XmlElement = content.CreateElement("group") bindingNode.AppendChild(group) Dim subGroup As XmlElement = content.CreateElement("subgroup") group.AppendChild(subGroup) Dim text As XmlElement = content.CreateElement("text") subGroup.AppendChild(text) text.SetAttribute("hint-style", "base") text.InnerText = "subgroup1" text = content.CreateElement("text") subGroup.AppendChild(text) text.SetAttribute("hint-style", "captionSubtle") text.InnerText = "captionSubtle" subGroup = content.CreateElement("subgroup") group.AppendChild(subGroup) text = content.CreateElement("text") subGroup.AppendChild(text) text.SetAttribute("hint-style", "captionSubtle") text.SetAttribute("hint-align", "right") text.InnerText = "subgroup2" text = content.CreateElement("text") subGroup.AppendChild(text) text.SetAttribute("hint-style", "captionSubtle") text.SetAttribute("hint-align", "right") text.InnerText = "captionSubtle" ' Save the toast markup as an XML file for debugging purposes content.Save("D:\Toast.xml") End Sub
按钮
处理以下事件并在通知中显示按钮:
- ToastNotificationsManager.UpdateToastContent ——添加一个按钮到通知,使用Arguments属性将数据传递给应用程序。
- ToastNotificationsManager.Activated ——处理按钮上的点击,将事件参数转换为ToastNotificationActivatedEventArgs类型,读取Arguments事件参数并从通知中获取数据。
下面的代码显示了示例处理程序。
C#:
using DevExpress.XtraBars.ToastNotifications; using System.Xml; // Add the "Show Details" button. private void toastNotificationsManager1_UpdateToastContent(object sender, DevExpress.XtraBars.ToastNotifications.UpdateToastContentEventArgs e) { XmlDocument content = e.ToastContent; XmlElement toastElement = content.GetElementsByTagName("toast").OfType<XmlElement>().FirstOrDefault(); XmlElement actions = content.CreateElement("actions"); toastElement.AppendChild(actions); XmlElement action = content.CreateElement("action"); actions.AppendChild(action); action.SetAttribute("content", "Show details"); action.SetAttribute("arguments", "viewdetails"); } // Handle button clicks. private void toastNotificationsManager1_Activated(object sender, DevExpress.XtraBars.ToastNotifications.ToastNotificationEventArgs e) { ToastNotificationActivatedEventArgs args = e as ToastNotificationActivatedEventArgs; MessageBox.Show(string.Format("The {0} button is clicked", args.Arguments)); }
VB.NET:
Imports DevExpress.XtraBars.ToastNotifications Imports System.Xml ' Add the "Show Details" button. Private Sub toastNotificationsManager1_UpdateToastContent(ByVal sender As Object, ByVal e As DevExpress.XtraBars.ToastNotifications.UpdateToastContentEventArgs) _ Handles toastNotificationsManager1.UpdateToastContent Dim content As XmlDocument = e.ToastContent Dim toastElement As XmlElement = content.GetElementsByTagName("toast").OfType(Of XmlElement)().FirstOrDefault() Dim actions As XmlElement = content.CreateElement("actions") toastElement.AppendChild(actions) Dim action As XmlElement = content.CreateElement("action") actions.AppendChild(action) action.SetAttribute("content", "Show details") action.SetAttribute("arguments", "viewdetails") End Sub ' Handle button clicks. Private Sub toastNotificationsManager1_Activated(ByVal sender As Object, ByVal e As DevExpress.XtraBars.ToastNotifications.ToastNotificationEventArgs) _ Handles toastNotificationsManager1.Activated Dim args As ToastNotificationActivatedEventArgs = TryCast(e, ToastNotificationActivatedEventArgs) MessageBox.Show(String.Format("The {0} button is clicked", args.Arguments)) End Sub
用户输入
Generic toast模板允许您向通知中添加。
C#:
private void toastNotificationsManager1_UpdateToastContent(object sender, DevExpress.XtraBars.ToastNotifications.UpdateToastContentEventArgs e) { XmlDocument content = e.ToastContent; XmlElement toastElement = content.GetElementsByTagName("toast").OfType<XmlElement>().FirstOrDefault(); toastElement.SetAttribute("launch", "performAction"); XmlElement actions = content.CreateElement("actions"); toastElement.AppendChild(actions); XmlElement text = content.CreateElement("input"); // Input Box actions.AppendChild(text); text.SetAttribute("id", "textBox"); text.SetAttribute("type", "text"); text.SetAttribute("placeHolderContent", "Type a reply"); // Time selector XmlElement input = content.CreateElement("input"); actions.AppendChild(input); input.SetAttribute("id", "time"); input.SetAttribute("type", "selection"); input.SetAttribute("defaultInput", "15min"); XmlElement selection = content.CreateElement("selection"); input.AppendChild(selection); selection.SetAttribute("id", "15min"); selection.SetAttribute("content", "15 minutes"); selection = content.CreateElement("selection"); input.AppendChild(selection); selection.SetAttribute("id", "30min"); selection.SetAttribute("content", "30 minutes"); XmlElement action = content.CreateElement("action"); // Send button actions.AppendChild(action); action.SetAttribute("content", "Send"); action.SetAttribute("arguments", "Send"); // Snooze button action = content.CreateElement("action"); actions.AppendChild(action); action.SetAttribute("content", "Snooze"); action.SetAttribute("arguments", "snooze"); // Dismiss button action = content.CreateElement("action"); actions.AppendChild(action); action.SetAttribute("content", "Dismiss"); action.SetAttribute("arguments", "dismiss"); }
VB.NET:
Private Sub toastNotificationsManager1_UpdateToastContent(ByVal sender As Object, ByVal e As DevExpress.XtraBars.ToastNotifications.UpdateToastContentEventArgs) Dim content As XmlDocument = e.ToastContent Dim toastElement As XmlElement = content.GetElementsByTagName("toast").OfType(Of XmlElement)().FirstOrDefault() toastElement.SetAttribute("launch", "performAction") Dim actions As XmlElement = content.CreateElement("actions") toastElement.AppendChild(actions) Dim text As XmlElement = content.CreateElement("input") ' Input Box actions.AppendChild(text) text.SetAttribute("id", "textBox") text.SetAttribute("type", "text") text.SetAttribute("placeHolderContent", "Type a reply") ' Time selector Dim input As XmlElement = content.CreateElement("input") actions.AppendChild(input) input.SetAttribute("id", "time") input.SetAttribute("type", "selection") input.SetAttribute("defaultInput", "15min") Dim selection As XmlElement = content.CreateElement("selection") input.AppendChild(selection) selection.SetAttribute("id", "15min") selection.SetAttribute("content", "15 minutes") selection = content.CreateElement("selection") input.AppendChild(selection) selection.SetAttribute("id", "30min") selection.SetAttribute("content", "30 minutes") Dim action As XmlElement = content.CreateElement("action") ' Send button actions.AppendChild(action) action.SetAttribute("content", "Send") action.SetAttribute("arguments", "Send") ' Snooze button action = content.CreateElement("action") actions.AppendChild(action) action.SetAttribute("content", "Snooze") action.SetAttribute("arguments", "snooze") ' Dismiss button action = content.CreateElement("action") actions.AppendChild(action) action.SetAttribute("content", "Dismiss") action.SetAttribute("arguments", "dismiss") End Sub
为了处理用户与这些元素的交互,创建一个Activator——DevExpress.XtraBars.ToastNotifications.ToastNotificationActivator类的自定义后代。用 和 属性修饰这个子类来允许组件对象模型(COM)创建和访问这个类的实例。在下面的示例中,一个消息框显示用户按下了哪个通知按钮、用户输入了什么文本以及用户选择了哪个时间间隔,更改OnActivate方法覆盖来实现您自己的功能。
C#:
[Guid("-type-your-GUID-here-"), ComVisible(true)] public class ToastNotificationActivatorCustom : DevExpress.XtraBars.ToastNotifications.ToastNotificationActivator { public override void OnActivate(string arguments, Dictionary<string, string> data) { StringBuilder sb = new StringBuilder(); sb.AppendLine(arguments); foreach (string key in data.Keys) { sb.AppendLine(string.Format("{0} = {1}", key, data[key])); } MessageBox.Show(sb.ToString()); } }
VB.NET:
<Guid("-type-your-GUID-here-"), ComVisible(True)> Public Class ToastNotificationActivatorCustom Inherits DevExpress.XtraBars.ToastNotifications.ToastNotificationActivator Public Overrides Sub OnActivate(ByVal arguments As String, ByVal data As Dictionary(Of String, String)) Dim sb As New StringBuilder() sb.AppendLine(arguments) For Each key As String In data.Keys sb.AppendLine(String.Format("{0} = {1}", key, data(key))) Next key MessageBox.Show(sb.ToString()) End Sub End Class
提示:您可以使用在线GUID generate随机生成有效的GUID。注意,所有GUID必须是唯一的。
注意:
- 如果您单击Toast通知管理器智能标签中的“Create Application Shortcut”链接来调试通知,则在每次更改Activator类时单击“Update Application Shortcut”链接。否则,通知将不会反映您的更改。
- 组件对象模型在工作线程中调用OnActivate方法,确保这个方法对控件和组件的所有调用都是用执行的。
要将这个自定义激活器分配给Toast通知管理器,请在设计时指定ToastNotificationsManager.ApplicationActivator属性。
…或在代码中调用RegisterApplicationActivator/UnregisterApplicationActivator方法(隐藏于智能感知)。
C#:
public XtraForm1() { InitializeComponent(); toastNotificationsManager1.RegisterApplicationActivator(typeof(ToastNotificationActivatorCustom)); this.FormClosed += XtraForm1_FormClosed; } private void XtraForm1_FormClosed(object sender, FormClosedEventArgs e) { toastNotificationsManager1.UnregisterApplicationActivator(); }
VB.NET:
Public Sub New() InitializeComponent() toastNotificationsManager1.RegisterApplicationActivator(GetType(ToastNotificationActivatorCustom)) AddHandler Me.FormClosed, AddressOf XtraForm1_FormClosed End Sub Private Sub XtraForm1_FormClosed(ByVal sender As Object, ByVal e As FormClosedEventArgs) toastNotificationsManager1.UnregisterApplicationActivator() End Sub
注意:
自定义激活器要求应用程序快捷方式包含一个唯一的应用程序ID (ToastNotificationsManager.ApplicationId)和一个指向COM类的CLSID(传递给GUID属性的GUID)。此外,应用程序必须注册为本地COM服务器,当用户与toast通知交互时可以调用该服务器。为此,在部署应用程序时创建以下注册表项:
- Key:HKEY_CURRENT_USER \ SOFTWARE \类{-your-GUID-here -} \ \ CLSID LocalServer32
- Value:C:\Users\Sample\Desktop\YourApplication.exe(指定可执行文件的实际路径)
应用快捷方式及故障处理
文章指出,要发送Toast通知,应用程序的快捷方式应该安装在启动画面上。启动画面应用程序快捷方式位于%AppData%\Microsoft\Windows\Start Menu\Programs文件夹中,您需要在该文件夹中添加快捷方式来显示toast通知。
作为一名开发人员,您可以调用ToastNotificationManager组件的智能标签,然后点击“Create Application Shortcut”来在机器上显示toast通知。然而,其他pc无法显示toast通知,因为他们的启动画面没有快捷方式到应用程序。
要在代码中添加启动画面快捷方式,请使用 DevExpress.Data.ShellHelper.TryCreateShortcut方法。
C#:
using DevExpress.XtraBars.ToastNotifications; using DevExpress.Data; ToastNotificationsManager manager = new ToastNotificationsManager(); manager.ApplicationId = "k2sjd104713413j134-981413das"; ToastNotification notification = new ToastNotification(); notification.Template = ToastNotificationTemplate.Text01; notification.Body = "DevExpress Toast Notification"; notification.ID = "lashdoiaqw2112lafhoar1op4"; manager.Notifications.Add(notification); if (!ShellHelper.IsApplicationShortcutExist("My Test App")) { ShellHelper.TryCreateShortcut( exePath: System.Reflection.Assembly.GetEntryAssembly().Location, applicationId: manager.ApplicationId, name: "My Test App"); Application.Restart(); }
VB.NET:
Imports DevExpress.XtraBars.ToastNotifications Imports DevExpress.Data Dim manager As New ToastNotificationsManager() manager.ApplicationId = "k2sjd104713413j134-981413das" Dim notification As New ToastNotification() notification.Template = ToastNotificationTemplate.Text01 notification.Body = "DevExpress Toast Notification" notification.ID = "lashdoiaqw2112lafhoar1op4" manager.Notifications.Add(notification) If Not ShellHelper.IsApplicationShortcutExist("My Test App") Then ShellHelper.TryCreateShortcut(exePath:= System.Reflection.Assembly.GetEntryAssembly().Location, applicationId:= manager.ApplicationId, name:= "My Test App") Application.Restart() End If
调用 Application.Restart 方法是因为如果应用程序正在运行,则Windows无法显示通知。这和其他潜在的问题(例如,应用程序可能没有在系统文件夹中写入文件的权限)意味着您不能依靠这种技术在 client机器上添加快捷方式,应用程序安装程序应该在“程序”文件夹中添加快捷方式,以便为您的用户启用toast通知。
要确保显示通知,请处理在无法显示通知时引发的ToastNotificationsManager.Failed 事件。例如,下面的代码说明了如何显示消息框而不是故障通知。
C#:
using DevExpress.XtraBars.ToastNotifications; using DevExpress.XtraEditors; private void ToastNotificationsManager1_Failed(object sender, ToastNotificationFailedEventArgs e) { if ((string)e.NotificationID == "important_notification_ID") { IToastNotificationProperties undeliveredToast = toastNotificationsManager1.GetNotificationByID(e.NotificationID); XtraMessageBox.Show(undeliveredToast.Body, undeliveredToast.Header); } }
VB.NET:
Imports DevExpress.XtraBars.ToastNotifications Imports DevExpress.XtraEditors Private Sub ToastNotificationsManager1_Failed(ByVal sender As Object, ByVal e As ToastNotificationFailedEventArgs) If CStr(e.NotificationID) = "important_notification_ID" Then Dim undeliveredToast As IToastNotificationProperties = toastNotificationsManager1.GetNotificationByID(e.NotificationID) XtraMessageBox.Show(undeliveredToast.Body, undeliveredToast.Header) End If End Sub
e.Exception事件参数允许您获取有关toast无法显示的原因的信息,还可以启用ToastNotificationsManager.ThrowOnErrors属性,以便在应用程序发送toast通知失败时抛出异常。
注意事项
- 操作系统会自动设置通知的背景颜色,您不能修改它。
- 操作系统显示通知,它们在最终用户关闭应用程序后仍然可见。
- Windows 8风格的通知会在右下角自动显示一个快捷图标,此图标无法移除。
- 同时显示的通知数量取决于最终用户的系统设置。
- Windows 10 Anniversary 更新(Redstone 1, build 1607)和更新的版本支持“Generic”通知模板。
- 如果通知没有为其AppLogoImage属性分配图像,它将显示应用程序图标,应用程序图标可以在的 “Project | Properties | Icon”菜单中设置。