NotificationService is an INotificationService implementation that allows you to show Windows 8 Style notifications.
Assume that you need to notify an end-user about some events in your application. To show the required notifications in Windows 8 style, you can use the NotificationService. Place the NotificationService into the Interaction.Behaviors collection as shown below.
<UserControl x:Class="DXSampleNotificationSevice.View.MainView"
...
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:ViewModel="clr-namespace:DXSampleNotificationSevice.ViewModel"
DataContext="{dxmvvm:ViewModelSource Type={x:Type ViewModel:MainViewModel}}">
...
<dxmvvm:Interaction.Behaviors>
<dxmvvm:NotificationService x:Name="AppNotificationService" UseWin8NotificationsIfAvailable="False"/>
</dxmvvm:Interaction.Behaviors>
...
</UserControl>
By default, NotificationService uses the native Windows 8 mechanism to show its notifications. An advantage of such notifications is that they can be shown over WinRT applications.
NotificationService displaying mechanism
To make NotificationService use its own mechanisms, it’s necessary to set the NotificationService.UseWin8NotificationsIfAvailable property to false. Otherwise, when the UseWin8NotificationsIfAvailable option is enabled, it’s necessary to use an appropriate NotificationService.ApplicationId.
This id should be specified in the application shortcut located in the “%APPDATA%\Roaming\Microsoft\Windows\Start Menu\Programs” directory. This is a requirement of the technology. To create a shortcut with the required application id, use our DevExpress.Data.ShellHelper class as shown below.
DevExpress.Data.ShellHelper.TryCreateShortcut([application id], [application name]);
DevExpress.Data.ShellHelper.TryCreateShortcut([application id], [application name])
Next, use the NotificationService from our View Model defined as a POCO object. If View Model is inherited from the ViewModelBase, use the approach from Services in ViewModelBase descendants.
[POCOViewModel]
public class MainViewModel {
[ServiceProperty(Key = "NotificationService")]
protected virtual INotificationService AppNotificationService { get { return null; } }
...
public void ShowNotification() {
INotification notification = AppNotificationService.CreatePredefinedNotification("Hello, world!", null, null, null);
notification.ShowAsync();
}
...
}
<POCOViewModel> _
Public Class MainViewModel
<ServiceProperty(Key := "NotificationService")> _
Protected Overridable ReadOnly Property AppNotificationService () As INotificationService
Get
Return Nothing
End Get
End Property
...
Public Sub ShowNotification()
Dim notification As INotification = AppNotificationService.CreatePredefinedNotification("Hello, world!", Nothing, Nothing, Nothing)
notification.ShowAsync()
End Sub
...
End Class
As you can see in the code snippet above, the notification is created via the NotificationService.CreatePredefinedNotification method with four parameters. The number of initialized parameters depends on which NotificationService.PredefinedNotificationTemplate is used by NotificationService. For instance, to fill out all fields in the ShortHeaderAndTwoTextFields template, you need specify the first three parameters. The last parameter is responsible for the image shown within the notification.
Create a custom notification
It is possible to specify your own notifications with a custom layout. To define a custom layout, use the NotificationService.CustomNotificationTemplate property as follows. Note that in this case, the NotificationService uses its own notifications, since the native mechanism doesn’t allow you to define notifications with a custom layout.
<UserControl x:Class="DXSampleNotificationSevice.View.MainView"
...
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:ViewModel="clr-namespace:DXSampleNotificationSevice.ViewModel"
DataContext="{dxmvvm:ViewModelSource Type={x:Type ViewModel:MainViewModel}}">
<UserControl.Resources>
<DataTemplate x:Key="CustomNotificationTemplate">
<Border Background="White" BorderThickness="1" BorderBrush="Black">
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBlock HorizontalAlignment="Left" Text="{Binding Caption}" Foreground="Blue" FontSize="20" FontWeight="Bold" Margin="5"/>
<TextBlock HorizontalAlignment="Center" Text="{Binding Content}" Foreground="Black" FontSize="16" Margin="3"/>
</StackPanel>
</Border>
</DataTemplate>
</UserControl.Resources>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:NotificationService x:Name="ServiceWithCustomNotifications" CustomNotificationTemplate="{StaticResource CustomNotificationTemplate}"/>
</dxmvvm:Interaction.Behaviors>
...
</UserControl>
To create a custom notification, use the NotificationService.CreateCustomNotification method, which requires a notification View Model as a parameter.
[POCOViewModel]
public class MainViewModel {
[ServiceProperty(Key = "ServiceWithCustomNotifications")]
protected virtual INotificationService CustomNotificationService { get { return null; } }
...
public void ShowCustomNotification() {
CustomNotificationViewModel vm = ViewModelSource.Create(() => new CustomNotificationViewModel());
vm.Caption = "Custom Notification";
vm.Content = String.Format("Time: {0}", DateTime.Now);
INotification notification = CustomNotificationService.CreateCustomNotification(vm);
notification.ShowAsync();
}
...
}
<POCOViewModel> _
Public Class MainViewModel
<ServiceProperty(Key := "ServiceWithCustomNotifications")> _
Protected Overridable ReadOnly Property CustomNotificationService() As INotificationService
Get
Return Nothing
End Get
End Property
...
Public Sub ShowCustomNotification()
Dim vm As CustomNotificationViewModel = ViewModelSource.Create(Function() New CustomNotificationViewModel())
vm.Caption = "Custom Notification"
vm.Content = String.Format("Time: {0}", Date.Now)
Dim notification As INotification = CustomNotificationService.CreateCustomNotification(vm)
notification.ShowAsync()
End Sub
...
End Class
To show the created notification, use the INotification.ShowAsync method. This method returns a NotificationResult enumeration value that depends on how the notification is shown and which element of the notification a user clicks.
- If a user clicks the displayed notification, the ShowAsync method returns the NotificationResult.Activated value.
- If a user clicks the notification’s close button in the top right corner, the ShowAsync method returns the NotificationResult.UserCanceled value.
- If the notification or its element wasn’t clicked during the time span specified in the NotificationService.CustomNotificationDuration or NotificationService.PredefinedNotificationDuration property, the ShowAsync method returns the NotificationResult.TimedOut value.
- If the notification was hidden programmatically using the INotification.Hide method, ShowAsync returns the NotificationResult.ApplicationHidden value.
- If the system’s notification queue is full and a new notification cannot be added, ShowAsync returns the NotificationResult.Dropped value.
Below is a code snippet illustrating how to process the result of the ShowAsync method.
public void ShowCustomNotification() {
CustomNotificationViewModel vm = ViewModelSource.Create(() => new CustomNotificationViewModel());
vm.Caption = "Custom Notification";
vm.Content = String.Format("Time: {0}", DateTime.Now);
INotification notification = CustomNotificationService.CreateCustomNotification(vm);
notification.ShowAsync().ContinueWith(result => OnContinueWith(result));
}
private void OnContinueWith(Task<NotificationResult> res) {
...
}
Public Sub ShowCustomNotification()
Dim vm As CustomNotificationViewModel = ViewModelSource.Create(Function() New CustomNotificationViewModel())
vm.Caption = "Custom Notification"
vm.Content = [String].Format("Time: {0}", DateTime.Now)
Dim notification As INotification = CustomNotificationService.CreateCustomNotification(vm)
notification.ShowAsync().ContinueWith(Function(result) OnContinueWith(result))
End Sub
Private Sub OnContinueWith(res As Task(Of NotificationResult))
...
End Sub
NotificationService sample project
Imports DevExpress.Mvvm.DataAnnotations
Namespace DXSampleNotificationSevice.ViewModel
<POCOViewModel> _
Public Class CustomNotificationViewModel
Public Overridable Property Caption() As String
Public Overridable Property Content() As String
End Class
End Namespace
Imports System.Windows
Namespace DXSampleNotificationSevice
Partial Public Class App
Inherits Application
Private Sub OnAppStartup_UpdateThemeName(ByVal sender As Object, ByVal e As StartupEventArgs)
DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName()
DevExpress.Data.ShellHelper.TryCreateShortcut("sample_notification_app", "DXSampleNotificationSevice")
End Sub
End Class
End Namespace
<UserControl x:Class="DXSampleNotificationSevice.View.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:ViewModel="clr-namespace:DXSampleNotificationSevice.ViewModel"
mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"
DataContext="{dxmvvm:ViewModelSource Type={x:Type ViewModel:MainViewModel}}">
<UserControl.Resources>
<DataTemplate x:Key="CustomNotificationTemplate">
<Border Background="White" BorderThickness="1" BorderBrush="Black">
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<TextBlock HorizontalAlignment="Left" Text="{Binding Caption}" Foreground="Blue" FontSize="20" FontWeight="Bold" Margin="5"/>
<TextBlock HorizontalAlignment="Center" Text="{Binding Content}" Foreground="Black" FontSize="16" Margin="3"/>
</StackPanel>
</Border>
</DataTemplate>
</UserControl.Resources>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:NotificationService x:Name="ServiceWithDefaultNotifications" ApplicationId="sample_notification_app" PredefinedNotificationTemplate="ShortHeaderAndTwoTextFields"/>
<dxmvvm:NotificationService x:Name="ServiceWithCustomNotifications" CustomNotificationTemplate="{StaticResource CustomNotificationTemplate}" CustomNotificationPosition="BottomRight" />
</dxmvvm:Interaction.Behaviors>
<Grid>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<Button Content="Default notification" Command="{Binding ShowDefaultNotificationCommand}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="2"/>
<Button Content="Custom notification" Command="{Binding ShowCustomNotificationCommand}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="2"/>
</StackPanel>
</Grid>
</UserControl>
Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Text
Imports System.Windows
Imports System.Windows.Controls
Imports System.Windows.Data
Imports System.Windows.Documents
Imports System.Windows.Input
Imports System.Windows.Media
Imports System.Windows.Media.Imaging
Imports System.Windows.Navigation
Imports System.Windows.Shapes
Namespace DXSampleNotificationSevice.View
''' <summary>
''' Interaction logic for MainView.xaml
''' </summary>
Partial Public Class MainView
Inherits UserControl
Public Sub New()
InitializeComponent()
End Sub
End Class
End Namespace
Imports System
Imports DevExpress.Mvvm
Imports DevExpress.Mvvm.DataAnnotations
Imports DevExpress.Mvvm.POCO
Namespace DXSampleNotificationSevice.ViewModel
<POCOViewModel> _
Public Class MainViewModel
<ServiceProperty(Key := "ServiceWithDefaultNotifications")> _
Protected Overridable ReadOnly Property DefaultNotificationService() As INotificationService
Get
Return Nothing
End Get
End Property
<ServiceProperty(Key := "ServiceWithCustomNotifications")> _
Protected Overridable ReadOnly Property CustomNotificationService() As INotificationService
Get
Return Nothing
End Get
End Property
Public Sub ShowDefaultNotification()
Dim notification As INotification = DefaultNotificationService.CreatePredefinedNotification("Predefined Notification", "First line", String.Format("Second line. Time: {0}", Date.Now), Nothing)
notification.ShowAsync()
End Sub
Public Sub ShowCustomNotification()
Dim vm As CustomNotificationViewModel = ViewModelSource.Create(Function() New CustomNotificationViewModel())
vm.Caption = "Custom Notification"
vm.Content = String.Format("Time: {0}", Date.Now)
Dim notification As INotification = CustomNotificationService.CreateCustomNotification(vm)
notification.ShowAsync()
End Sub
End Class
End Namespace
using DevExpress.Mvvm.DataAnnotations;
namespace DXSampleNotificationSevice.ViewModel {
[POCOViewModel]
public class CustomNotificationViewModel {
public virtual string Caption { get; set; }
public virtual string Content { get; set; }
}
}
using System;
using DevExpress.Mvvm;
using DevExpress.Mvvm.DataAnnotations;
using DevExpress.Mvvm.POCO;
namespace DXSampleNotificationSevice.ViewModel {
[POCOViewModel]
public class MainViewModel {
[ServiceProperty(Key = "ServiceWithDefaultNotifications")]
protected virtual INotificationService DefaultNotificationService { get { return null; } }
[ServiceProperty(Key = "ServiceWithCustomNotifications")]
protected virtual INotificationService CustomNotificationService { get { return null; } }
public void ShowDefaultNotification() {
INotification notification = DefaultNotificationService.CreatePredefinedNotification("Predefined Notification", "First line", String.Format("Second line. Time: {0}", DateTime.Now), null);
notification.ShowAsync();
}
public void ShowCustomNotification() {
CustomNotificationViewModel vm = ViewModelSource.Create(() => new CustomNotificationViewModel());
vm.Caption = "Custom Notification";
vm.Content = String.Format("Time: {0}", DateTime.Now);
INotification notification = CustomNotificationService.CreateCustomNotification(vm);
notification.ShowAsync();
}
}
}
using System.Windows;
namespace DXSampleNotificationSevice {
public partial class App : Application {
private void OnAppStartup_UpdateThemeName(object sender, StartupEventArgs e) {
DevExpress.Xpf.Core.ApplicationThemeHelper.UpdateApplicationThemeName();
DevExpress.Data.ShellHelper.TryCreateShortcut("sample_notification_app", "DXSampleNotificationSevice");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace DXSampleNotificationSevice.View {
/// <summary>
/// Interaction logic for MainView.xaml
/// </summary>
public partial class MainView : UserControl {
public MainView() {
InitializeComponent();
}
}
}