windowsforms-17020-controls-and-libraries-messages-notifications-and-dialogs-toast-notification-manager.md
The Toast Notification Manager component displays native Windows toast notifications (Windows 8+).
Note
You can display a single notification multiple times or display multiple distinct notifications. The Toast Notification Manager supports nine alert templates and sound notifications.
Turn on notifications from apps in Windows OS:
The following code snippet creates a Toast Notification Manager , adds and displays a Backup Completed notification:
using DevExpress.XtraBars.ToastNotifications;
// Create a Toast Notification Manager.
var manager = new ToastNotificationsManager();
manager.ApplicationId = "your-app-id"; // Unique ID
// Add a notification.
var note = new ToastNotification();
note.Template = ToastNotificationTemplate.Text02;
note.Header = "Backup Completed";
note.Body = "Database backup finished.";
note.ID = Guid.NewGuid().ToString(); // A unique identifier
manager.Notifications.Add(note);
// Display the notification.
manager.ShowNotification(note.ID);
Drop the ToastNotificationsManager component from the toolbox onto a form.
Ensure your application has a valid shortcut with an Application User Model ID. Windows displays toast notifications for apps that are pinned to the Start menu.
Select the ToastNotificationsManager component, open its smart tag menu, and click Edit Notifications.
In the Collection Editor dialog, click Add to create a notification.
Configure notification properties.
Templates:
|
Template Name
|
Image
|
Notes
| | --- | --- | --- | |
Text01
|
|
The description (Body). Maximum three lines.
| |
Text02
|
|
The header and description (two lines).
| |
Text03
|
|
The header (two lines) and description (one line).
| |
Text04
|
|
The header and description (Body and Body2).
| |
ImageAndText01
|
|
The description (Body) and image. Maximum three lines.
| |
ImageAndText02
|
|
The header, description (two lines), and image.
| |
ImageAndText03
|
|
The header (two lines), description (one line), image.
| |
ImageAndText04
|
|
The header, description (Body and Body2), and image.
| |
Generic
|
|
Windows 10 style. Properties:
|
| Method | Description |
|---|---|
| ShowNotification | Displays the specified notification. |
| HideNotification | Hides the specified notification. |
| HideNotifications | Hides all notifications. |
toastNotificationsManager1.ShowNotification(toastNotificationsManager1.Notifications[3]);
toastNotificationsManager1.ShowNotification("3b7fcd8b-a1e0-4ff5-83ce-023cdf6be24b");
| Event | Description |
|---|---|
| Activated | The user clicks the notification. |
| UserCancelled | The user closes the notification. |
| TimedOut | The user does not interact with the notification, and it is automatically hidden after a predefined interval. |
| Hidden | The notification is hidden programmatically. |
| Dropped | The notification is canceled by the operating system based on the user’s system settings. |
The following code snippet handles the ToastNotificationsManager.Activated event to identify which notification the user clicked and display a corresponding message.
void toastNotificationsManager1_Activated(object sender, 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;
}
}
Sub toastNotificationsManager1_Activated(sender As Object, e As 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
The following code snippet handles the ToastNotificationsManager.TimedOut event to resend timed out notifications:
private void toastNotificationsManager1_TimedOut(object sender, DevExpress.XtraBars.ToastNotifications.ToastNotificationEventArgs e) {
toastNotificationsManager1.ShowNotification(e.NotificationID);
}
Private Sub toastNotificationsManager1_TimedOut(sender As Object, e As DevExpress.XtraBars.ToastNotifications.ToastNotificationEventArgs)
toastNotificationsManager1.ShowNotification(e.NotificationID)
End Sub
The following XML markup defines the content layout of a toast notification:
<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>
Handle the ToastNotificationsManager.UpdateToastContent to modify the XML template programmatically with the System.Xml API. The following code snippet adds a group element with two subgroups to the layout. Each subgroup includes two additional text elements arranged vertically.
using System.Xml;
public Form1() {
InitializeComponent();
//...
toastNotificationsManager1.UpdateToastContent += ToastNotificationsManager1_UpdateToastContent;
}
void ToastNotificationsManager1_UpdateToastContent(object sender, UpdateToastContentEventArgs e) {
XmlDocument content = e.ToastContent;
XmlNode bindingNode = content.GetElementsByTagName("binding")[0];
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 XML to a file for debugging.
content.Save(@"D:\Toast.xml");
}
Imports System.Xml
Public Sub New()
InitializeComponent()
'...
AddHandler toastNotificationsManager1.UpdateToastContent, AddressOf ToastNotificationsManager1_UpdateToastContent
End Sub
Sub ToastNotificationsManager1_UpdateToastContent(ByVal sender As Object, ByVal e As UpdateToastContentEventArgs)
Dim content As XmlDocument = e.ToastContent
Dim bindingNode As XmlNode = content.GetElementsByTagName("binding")(0)
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 XML to a file for debugging.
content.Save("D:\Toast.xml")
End Sub
Tip
See the following article for additional information: App Notification Content.
Handle the following events to display buttons within toast notifications and handle button clicks:
| Event | Description |
|---|---|
| UpdateToastContent | Handle this event to display a button within the notification. |
| Activated | Handle button clicks. |
The following code snippet displays the Show Details button within toast notifications:
using DevExpress.XtraBars.ToastNotifications;
using System.Xml;
// Display the "Show Details" button.
void toastNotificationsManager1_UpdateToastContent(object sender, 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.
void toastNotificationsManager1_Activated(object sender, ToastNotificationEventArgs e) {
ToastNotificationActivatedEventArgs args = e as ToastNotificationActivatedEventArgs;
MessageBox.Show(string.Format("The {0} button is clicked", args.Arguments));
}
Imports DevExpress.XtraBars.ToastNotifications
Imports System.Xml
' Display the "Show Details" button.
Private Sub toastNotificationsManager1_UpdateToastContent(ByVal sender As Object, ByVal e As 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 ToastNotificationEventArgs) _
Handles toastNotificationsManager1.Activated
Dim args As ToastNotificationActivatedEventArgs = TryCast(e, ToastNotificationActivatedEventArgs)
MessageBox.Show(String.Format("The {0} button is clicked", args.Arguments))
End Sub
The Generic toast template allows you to display input boxes and dropdown menus within notifications.
void toastNotificationsManager1_UpdateToastContent(object sender, 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");
}
Private Sub toastNotificationsManager1_UpdateToastContent(ByVal sender As Object, ByVal e As 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
To handle user interactions with these elements, create an Activator – a custom descendant of the DevExpress.XtraBars.ToastNotifications.ToastNotificationActivator class. Decorate this descendant with ComVisible and Guid attributes to allow the Component Object Model (COM) to create and access instances of this class.
To handle user interactions with inputs and dropdown menus, implement an Activator — a custom class derived from DevExpress.XtraBars.ToastNotifications.ToastNotificationActivator. Apply ComVisible and Guid attributes to allow the Component Object Model (COM) to create and access class instances.
The following code snippet implements ToastNotificationActivatorCustom. The activator displays a message box with the following information:
[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());
}
}
<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
Warning
All GUIDs must be unique. Use GUID generators to randomly generate a valid GUID.
Important
OnActivate method on a worker thread. Ensure that all calls to controls and components from this method are made in a thread-safe way.To assign a custom Activator to the Toast Notification Manager at design time, use the ToastNotificationsManager.ApplicationActivator property:
At runtime, use RegisterApplicationActivator/UnregisterApplicationActivator methods. These methods are hidden from IntelliSense.
public XtraForm1() {
InitializeComponent();
toastNotificationsManager1.RegisterApplicationActivator(typeof(ToastNotificationActivatorCustom));
this.FormClosed += XtraForm1_FormClosed;
}
private void XtraForm1_FormClosed(object sender, FormClosedEventArgs e) {
toastNotificationsManager1.UnregisterApplicationActivator();
}
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
Important
The Custom Activator requires that the application shortcut includes a unique application ID (ToastNotificationsManager.ApplicationId) and a CLSID that points to your COM class (a GUID specified in the Guid attribute). You must register your application as a local COM server so it can be invoked when users interact with toast notifications. To do this, create the following registry key during deployment:
Key: HKEY_CURRENT_USER\SOFTWARE\Classes\CLSID{–your-GUID-here–}\LocalServer32Value: C:\Users\Sample\Desktop\YourApplication.exe (replace with the actual path to your executable)An application must have a shortcut installed on the Start screen to display toast notifications. Start screen shortcuts are located in the %AppData%\Microsoft\Windows\Start Menu\Programs folder. You must add a shortcut to this folder to display toast notifications.
Open the Toast Notification Manager ‘s smart tag menu and click Create Application Shortcut to display toast notifications on your machine. Note that other PCs will not display toast notifications unless they also have a shortcut to your application on their Start screen.
To add a Start screen shortcut in code, use the DevExpress.Data.ShellHelper.TryCreateShortcut method.
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();
}
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
Tip
The Application.Restart method is required because Windows cannot display toast notifications while the application is running. To enable toast notifications on client machines, your application installer should create a shortcut in the Programs folder.
To handle cases where a notification cannot be displayed, subscribe to the ToastNotificationsManager.Failed event. The following code snippet displays a message box if the notification fails to display.
using DevExpress.XtraBars.ToastNotifications;
using DevExpress.XtraEditors;
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);
}
}
Imports DevExpress.XtraBars.ToastNotifications
Imports DevExpress.XtraEditors
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
The e.Exception event parameter contains information about why a toast notification could not be displayed. You can also enable the ToastNotificationsManager.ThrowOnErrors option to throw exceptions when the application fails to send a toast notification.