How to Show Toast Notifications in WinForms Apps

WinForms Team Blog
10 February 2020

Toast Notifications (or simply Toasts) are flat notifications first introduced in Microsoft Windows 8. They pop up in the bottom right corner of your screen and can be accessed through the Windows Action Center. You can incorporate these notifications in your next Windows Forms app by using the DevExpress ToastNotificationManager component. To see toasts in action, launch our "Outlook Inspired App" demo and wait for it to load its notifications.

Our WinForms Toast Notification Manager offers nine notification templates/styles - including a Windows 10 "Generic" template that allows you to incorporate user interaction controls such as buttons or editors.

Application Shortcut

The DevExpress WinForms Toast Notification Manager generates genuine Windows toasts. These toasts are just like system notifications:

  • Toasts appear even if the associated application is closed.
  • Toasts can be accessed from the Action Center.
  • Toasts use the same color scheme as the operating system.

To deliver this capability, we had to use native Windows APIs and follow all Microsoft guidelines and requirements. This included Microsoft’s application shortcut requirement.

Unfortunately, Microsoft’s application shortcut requirement has caused some confusion in the past. We recently made a minor design-time improvement and added a new section to the component's documentation page to help address this issue going forward.

In its Toast Notifications Overview Microsoft explicitly states that if an app does not have a shortcut in the Windows Start screen, it cannot display toasts.

Since Start screen shortcuts are stored in the %AppData%\Microsoft\Windows\Start Menu\Programs folder, we need to follow a simple rule: To display toasts, add an application shortcut to Start Menu folder.

Our component includes a "Create Application Shortcut" link in its smart tag menu. Once you click this link, your app will correctly display notifications.

As some of you have discovered, our "Create Application Shortcut" command adds a shortcut to one’s personal Start screen. Said differently, the PC that created the application shortcut is the only machine able to display toasts… No other machine’s Start screen has a shortcut to your app. If you want to display toasts for all users (and not just yourself), remember to configure your application installer to add a shortcut (with a valid AppUserModelID) in the %AppData%\Microsoft\Windows\Start Menu\Programs folder.

We believe that your best option is to use an installer to add this shortcut to user machines. If this is not an option or if you don’t have an installer, you can use the DevExpress.Data.ShellHelper.TryCreateShortcut method to add the appropriate shortcut.

using DevExpress.XtraBars.ToastNotifications;
using DevExpress.Data;

//if there's no app shortcut in the start screen, add it
if (!ShellHelper.IsApplicationShortcutExist("My Test App")) {
    ShellHelper.TryCreateShortcut(
        applicationId: manager.ApplicationId,
        name: "My Test App");
    //restart the app
    Application.Restart();
}

Please note that the TryCreateShortcut method is less reliable than the alternative. First and most important - your app may not have the necessary permissions to write files into system folders. Second, note the use of the Application.Restart method in the code snippet above. If the application is already running, adding its shortcut to the Start screen will not enable toasts. Application restart is required.

Activator and COM Server

Windows retains toast notifications in its Action Center.

Normally, Action Center clears all toasts after a user closes this screen (if a user opens, closes, and opens the Action Center again, it will be empty). Some toasts, however, can remain in the Action Center until a user manually dismisses them. Such toasts remain in the Action Center even after a user logs out and back into Windows. Additionally, these toasts launch their parent applications when clicked. To display such notifications, create a custom Activator - a descendant of the DevExpress.XtraBars.ToastNotifications.ToastNotificationActivator class.

[Guid("39697E4E-3543-4414-A694-90097B433DC6"), ComVisible(true)]
public class ToastNotificationActivatorCustom : ToastNotificationActivator {

    public override void OnActivate(string arguments, Dictionary<string, string> data){
        //specify what happens when a user interacts with a toast
    }
}

You will need to register this custom Activator. Set the component's ApplicationActivator property at design time or call the RegisterApplicationActivator method in code.

toastNotificationsManager1.RegisterApplicationActivator(
		typeof(ToastNotificationActivatorCustom));

You will also need to register a COM Server. To do so, call the DevExpress.Data.ShellHelper.RegisterComServer method. Note that if you use the ShellHelper class to create an application shortcut, you need to use a TryCreateShortcut method overload that takes the activatorType parameter. Otherwise, if you use the application installer to add the application shortcut, the installer must also add the HKEY_CURRENT_USER\SOFTWARE\Classes\CLSID\{-your-GUID-here-}\LocalServer32 registry key with a path to application executable file as a value.

if (!ShellHelper.IsApplicationShortcutExist("My Toast Application")
{
    ShellHelper.TryCreateShortcut(
         Process.GetCurrentProcess().MainModule.FileName,
         toastNotificationsManager1.ApplicationId,
         "My Toast Application",
         @"D:\Work\Images\_Icons\ico\chain-icon.ico",
         typeof(ToastNotificationActivatorCustom));
    ShellHelper.RegisterComServer(
        Process.GetCurrentProcess().MainModule.FileName,
        typeof(ToastNotificationActivatorCustom));
}

GUIDs

When working with toasts, you will need several unique IDs.

  • For the component's ApplicationID property
  • For the ID property of every notification
  • For the Guid attribute that labels an Activator class

You can mash a keyboard to generate a unique ID, but a more effective approach is to use an online GUID generator (such as this one) or the generator included in Visual Studio ("Tools | Create GUID").

Deliver Critical Notifications

Even if you set up everything correctly, a notification may not delivered to a user. Delivery can be affected by:

  • an older OS version
  • notifications disabled in Action Center settings
  • internal errors, etc.

In such circumstances, you can handle the ToastNotificationsManager.Failed event to deliver critical messages to users via alternative methods (such as a standard message box).

using DevExpress.XtraBars.ToastNotifications;
using DevExpress.XtraEditors;

void manager_Failed(object sender, ToastNotificationFailedEventArgs e)
{
    if ((string)e.NotificationID == "toast_connection_lost_id_das0ud0q94")
    {
        IToastNotificationProperties undeliveredToast =
            toastNotificationsManager1.GetNotificationByID(e.NotificationID);
        XtraMessageBox.Show(undeliveredToast.Body, undeliveredToast.Header);
    }
}

Should you have any questions about Toast Notifications or you encounter issues with implementation, please post comments below. We’ll be happy to follow up.

Showcase Your Apps on DevExpress.com

Highlight your business app and share your development experiences with the DevExpress community. To include your app in our upcoming App Showcase, please forward an application screenshot to clientservices@devexpress.com and tell us which DevExpress products you currently use within your organization.
4 comment(s)
Christopher Jay
Christopher Jay
This is nice.  I like the Failed event so I can handle the old OSes and fallback to our old toasts.  Looking forward to implementing soon.  Thanks!
10 February 2020
DANIEL SASS
DANIEL SASS
Is there/will there be an equivalent in WPF?
11 February 2020
Alex Chuev (DevExpress)
Alex Chuev (DevExpress)

Daniel,


You can display toast notifications in WPF apps using the NotificationService class from our MVVM Framework.


Thanks,

Alex

11 February 2020
Benjamin Hofmann
Benjamin Hofmann
Great article!
11 February 2020

Please login or register to post comments.