Toast通知管理器
Toast Notification Manager組件顯示Toast通知——一個Windows 10版本的警報窗口。
提示:
- Toast通知只能在Windows 8.0或更高版本下顯示,對于較舊的Windows版本,請使用警報窗口。
- Windows只對那些固定在“開始”菜單上的應用程序顯示toast通知。
- 如果用戶禁用了通知(特定于應用程序的通知或所有通知),Toast通知管理器將無法顯示通知。
- 該組件使用系統(tǒng)的COM對象將通知數(shù)據(jù)傳遞給Windows通知平臺,Windows根據(jù)這些數(shù)據(jù)顯示通知。如果您的應用程序或用戶沒有訪問Windows通知平臺的權限,則不會彈出通知。
應用程序可以同時顯示多個通知,也可以一次多次顯示一個通知。ToastNotification對象有9個內容模板,可以播放聲音。
創(chuàng)建通知
1.將ToastNotificationManager組件從Visual Studio的工具箱中拖放到表單上。
3.調用管理器的智能標記并單擊Edit Notifications…鏈接。
4.在集合編輯器對話框中,單擊 Add 添加通知,這會創(chuàng)建新的ToastNotification對象,并將它們添加到管理器的ToastNotificationsManager.Notifications集合中,您可以自定義屬性網(wǎng)格中的通知設置。
- ToastNotification.Body和IToastNotificationProperties.Body2 ——兩個常規(guī)文本字符串,它們是主要的通知文本。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文本占據(jù)第一行和第二行,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")
管理終端用戶交互
根據(jù)用戶的操作,會發(fā)生以下事件:
- ToastNotificationsManager. Activated ——如果最終用戶單擊此通知,則發(fā)生,處理此事件來檢查單擊了哪個通知,并根據(jù)結果執(zhí)行操作。下面的代碼演示了一個示例。
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——在最終用戶關閉通知時發(fā)生。
- ToastNotificationsManager.TimedOut——在最終用戶沒有響應通知并且在一段時間后隱藏通知時發(fā)生,下面的代碼重新發(fā)送超時通知。
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方法隱藏時發(fā)生。
- ToastNotificationsManager.Dropped—當通知因最終用戶的系統(tǒng)設置而取消時觸發(fā)。
使用“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屬性將數(shù)據(jù)傳遞給應用程序。
- ToastNotificationsManager.Activated ——處理按鈕上的點擊,將事件參數(shù)轉換為ToastNotificationActivatedEventArgs類型,讀取Arguments事件參數(shù)并從通知中獲取數(shù)據(jù)。
下面的代碼顯示了示例處理程序。
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
為了處理用戶與這些元素的交互,創(chuàng)建一個Activator——DevExpress.XtraBars.ToastNotifications.ToastNotificationActivator類的自定義后代。用 ComVisible 和 Guid 屬性修飾這個子類來允許組件對象模型(COM)創(chuàng)建和訪問這個類的實例。在下面的示例中,一個消息框顯示用戶按下了哪個通知按鈕、用戶輸入了什么文本以及用戶選擇了哪個時間間隔,更改OnActivate方法覆蓋來實現(xiàn)您自己的功能。
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方法,確保這個方法對控件和組件的所有調用都是用線程安全的方式執(zhí)行的。
要將這個自定義激活器分配給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通知交互時可以調用該服務器。為此,在部署應用程序時創(chuàng)建以下注冊表項:
- Key:HKEY_CURRENT_USER \ SOFTWARE \類{-your-GUID-here -} \ \ CLSID LocalServer32
- Value:C:\Users\Sample\Desktop\YourApplication.exe(指定可執(zhí)行文件的實際路徑)
應用快捷方式及故障處理
Microsoft Toast notification overview 文章指出,要發(fā)送Toast通知,應用程序的快捷方式應該安裝在啟動畫面上。啟動畫面應用程序快捷方式位于%AppData%\Microsoft\Windows\Start Menu\Programs文件夾中,您需要在該文件夾中添加快捷方式來顯示toast通知。
作為一名開發(fā)人員,您可以調用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無法顯示通知。這和其他潛在的問題(例如,應用程序可能沒有在系統(tǒng)文件夾中寫入文件的權限)意味著您不能依靠這種技術在 client機器上添加快捷方式,應用程序安裝程序應該在“程序”文件夾中添加快捷方式,以便為您的用戶啟用toast通知。
要確保顯示通知,請?zhí)幚碓跓o法顯示通知時引發(fā)的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事件參數(shù)允許您獲取有關toast無法顯示的原因的信息,還可以啟用ToastNotificationsManager.ThrowOnErrors屬性,以便在應用程序發(fā)送toast通知失敗時拋出異常。
注意事項
- 操作系統(tǒng)會自動設置通知的背景顏色,您不能修改它。
- 操作系統(tǒng)顯示通知,它們在最終用戶關閉應用程序后仍然可見。
- Windows 8風格的通知會在右下角自動顯示一個快捷圖標,此圖標無法移除。
- 同時顯示的通知數(shù)量取決于最終用戶的系統(tǒng)設置。
- Windows 10 Anniversary 更新(Redstone 1, build 1607)和更新的版本支持“Generic”通知模板。
- 如果通知沒有為其AppLogoImage屬性分配圖像,它將顯示應用程序圖標,應用程序圖標可以在Visual studio的 “Project | Properties | Icon”菜單中設置。