Skip to main content

DevExpress v24.1 Update — Your Feedback Matters

Our What's New in v24.1 webpage includes product-specific surveys. Your response to our survey questions will help us measure product satisfaction for features released in this major update and help us refine our plans for our next major release.

Take the survey Not interested

Lesson 9 - Show Windows 8-style Toast Notifications

  • 4 minutes to read

Windows 8 style toast notifications allow you to notify the user about some events even if the application is not currently active. The DevExpress NotificationService enables you to show native Windows 8 notifications in a MVVM style and even simulate them in earlier versions of Windows.

In this lesson, you will learn how to notify the user when a new task is assigned to an employee.

#Step 1 - Adding necessary Services to the View

To use the INotificationService interface from a view model, register the corresponding service interface implementation in the corresponding view.

Open the DevAVDbView.xaml file in the designer and invoke the Document Outline window (VIEW | Other Windows | Document Outline). In the Document Outline window, select the root UserControl, open its smart tag and select the MVVM Behaviors and Services tab. Click the Add Service item and choose the NotificationService from the menu.

outlook_tut_les9_1

Select the added service and set its PredefinedNotificationDuration property to Long, the PredefinedNotificationTemplate property to ShortHeaderAndLongText, UseWin8NotificationsIfAvailable to False.

outlook_tut_les9_2

You also need the IDocumentManagerService to show information about a new task. Use the Add Service item to add the WindowedDocumentUIService and name it SingleObjectDocumentManagerService.

outlook_tut_les9_3

#Step 2 - Using INotificationService from the view model

The idea is to track when a new task is added and store its Id.

long maxTaskId;
    static long GetLastTaskId() {
        return UnitOfWorkSource.GetUnitOfWorkFactory().CreateUnitOfWork().Tasks.Max(x => x.Id);
    }

Every 3 seconds a request for the last Id is being called and if it has been changed, a notification is shown. If a customer clicks the notification, the SingleObjectDocumentManagerService is used to show information about the new task.

IDocumentManagerService SingleObjectDocumentManagerService { get { return this.GetService<IDocumentManagerService>("SignleObjectDocumentManagerService"); } }
    public override void OnLoaded() {
        base.OnLoaded();
        maxTaskId = GetLastTaskId();
        var timer = new DispatcherTimer();
        timer.Interval = new TimeSpan(0, 0, 0, 3);
        timer.Tick += OnTimerTick;
        timer.Start();
    }
    void OnTimerTick(object sender, EventArgs e) {
        long currentMaxTaskId = GetLastTaskId();
        if(currentMaxTaskId != maxTaskId) {
            maxTaskId = currentMaxTaskId;
            var task = UnitOfWorkSource.GetUnitOfWorkFactory().CreateUnitOfWork().Tasks.FirstOrDefault(x => x.Id == maxTaskId);
            if(task != null) {
                var notificationService = this.GetRequiredService<INotificationService>();
                var notification = notificationService.CreatePredefinedNotification(string.Format("New task assigned to {0}", task.AssignedEmployee.FullName), task.Subject, string.Empty);
                notification
                    .ShowAsync()
                    .ContinueWith(t =>
                {
                    if(t.Result == NotificationResult.Activated)
                        SingleObjectDocumentManagerService.ShowExistingEntityDocument<EmployeeTask, long>(this, maxTaskId);
                }, TaskScheduler.FromCurrentSynchronizationContext());
            }
        }
    }

It is necessary to track whether a new task has been created in the same instance of the application.

public override void OnLoaded() {
            base.OnLoaded();
            Messenger.Default.Register<EntityMessage<EmployeeTask, long>>(this, OnEmployeeTaskMessage);
                //...
        }
        void OnEmployeeTaskMessage(EntityMessage<EmployeeTask, long> message) {
            if(message.MessageType == EntityMessageType.Added)
                maxTaskId = message.PrimaryKey;
        }

This approach is not perfect. For example, if more than one task is created between two Id requests, only one notification will be shown. However, this behavior is enough for demonstration purposes.

#Step 3 - Testing the Functionality

Run two instances of the application and double-click any employee in the first instance. In the employee editing form, scroll to the Assigned Tasks grid and click the New action.

outlook_tut_les9_4

In the new task editing form, fill the Subject and Description fields and save the task.

outlook_tut_les9_5

Within 3 seconds, a toast notification will appear in the upper right corner of the screen.

outlook_tut_les9_6

Click the notification to show the task editing form in the second instance of the application.

Applications that contain the result of this lesson are available here: DevExpress.OutlookInspiredApp and DevExpress.HybridApp.

See Also