Just download the project demo, restore the missing packages using Nuget and enjoy. ![Smile | :)](http://codeproject.cachefly.net/script/Forums/Images/smiley_smile.gif)
Fancy toast notification for WPF applications easy to use and support MVVM pattern. A small notification window with image, title and content displayed at the bottom of the screen. You can use the default implementation or build your own custom notification.
Github
You can check out the project on Github from here, download the source code and the App demo and enjoy. ![Smile | :)](http://codeproject.cachefly.net/script/Forums/Images/smiley_smile.gif)
The demo demonstrates how to use the toast notification to display it with the default implementation or with your own custom implementation.
Nuget
WPF Toast Notification is available on NuGet, you can install it using nuget manager or run the following command in the package manager console.
PM> Install-Package WPFNotification
Note: In the WPF Toast Notification - Deep Dive article, I explained step by step the code behind the package.
In this article, we will demonstrate
- Simple, lightweight and fancy toast notification with title, content and overridable predefined image displayed at the bottom of the screen.
- Support MVVM pattern.
- Adds support for windows 7 or later.
- Adds support for displaying notification on different screen resolution.
- Configurable, you can use the default notification configuration or reconfigure it with the following attributes:
- Display duration
- Width
- Height
- Notification template
- Notification Flow Direction,That set direction in which new notification window will appear. Available options are:
- RightBottom (default).
- LeftBottom.
- LeftUp.
- RightUp.
- Customizable
- You can implement your own notification
- Show one notification per time and if there are other notifications, they will be placed in a queue and will be shown when the place is available.
- Prevent the notification from fading out when hovering on it.
- Allow to clear all notifications from notification list and notification buffer list
Adding the Notification Assembly
- Open Visual Studio and open an existing WPF application or create a new WPF Application project.
- Get the latest
WPFToastNotification
release and unzip its contents to disk or install the WPFNotification package using NuGet. - Add an assembly reference to WPFNotification.dll.
- Modify the App.xaml and add the following resource dictionary reference:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/WPFNotification;component/Assets/NotificationUI.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Notet :
If you install WPFNotification package using NuGet. Automatically it will add the assembly reference and modify the App.xaml file for you.
Assuming that the notification will be displayed when the user clicks on a button:
- If you are using MVVM pattern, you need to do the following steps:
- Register the
INotificationDialogService
into your IOC container. I am using SimpleIOC
container.
SimpleIoc.Default.Register<INotificationDialogService, NotificationDialogService>();
- Inject
INotificationDialogService
into your viewModel
. - Create
Notification
object with your Title
, Message
and optional ImgURL
(if null
, it will display the default predefined image). - Finally, call the
ShowNotificationWindow
method with the notification object.
public class MainViewModel : ViewModelBase
{
private readonly INotificationDialogService _dailogService;
public MainViewModel(INotificationDialogService dailogService)
{
_dailogService = dailogService;
}
private RelayCommand _defaultNotification;
public RelayCommand DefaultNotification
{
get
{
return _defaultNotification
?? (_defaultNotification = new RelayCommand(
() =>
{
var newNotification = new Notification()
{
Title = "Machine error",
Message = "Error!! Please check your Machine Code and Try Again"
};
_dailogService.ShowNotificationWindow(newNotification);
}));
}
}
}
- If you are using Code-Behind, you need to do the following steps:
- Create
INotificationDialogService
object. - Create
Notification
object with your Title
, Message
and optional ImgURL
(if null
, it will display the default predefined image). - Finally, call the
ShowNotificationWindow
method with the notification object.
private void Button_Click(object sender, RoutedEventArgs e)
{
INotificationDialogService _dailogService = new NotificationDialogService();
var newNotification = new Notification()
{
Title = "Machine error",
Message = "Error!! Please check your Machine Code and Try Again"
};
_dailogService.ShowNotificationWindow(newNotification);
}
Now you should see the notification on your screen like the figure below:
![](http://www.codeproject.com/KB/WPF/1073989/Default_Notification_with_newImage.png)
Assuming that we will create mail Notification that will be displayed when user clicks on a button.
To create custom notification, we need to do five steps:
Step 1
Create custom notification model, e.g., MailNotification
class like below:
public class MailNotification
{
public string Title { get; set; }
public string Sender { get; set; }
public string Content { get; set; }
}
Note:
If you want to use the default notification model, but you need to change the notification UI, you should ignore this step and start from step 2.
Step 2
Create the custom Notification UI, e.g. NotificationItem.xaml (user control) and bind it to the MailNotification
model like below:
<UserControl x:Class="WPFNotificationDemo.Assets.NotificationItem"
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"
mc:Ignorable="d"
xmlns:self="ASTA.Host.Presentation.Views.Notifications"
d:DesignHeight="180" d:DesignWidth="320"
x:Name="NotificationWindow"
Background="Transparent">
<UserControl.Triggers>
<EventTrigger RoutedEvent="Button.Click" SourceName="CloseButton">
<BeginStoryboard>
<Storyboard >
<DoubleAnimation Storyboard.TargetName="NotificationWindow"
From="1" To="0"
Storyboard.TargetProperty="(Grid.Opacity)" Duration="0:0:0"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</UserControl.Triggers>
<UserControl.Style>
<Style TargetType="UserControl">
<Style.Triggers>
<DataTrigger Binding="
{Binding ElementName=NotificationWindow,Path=Opacity}" Value="0"/>
</Style.Triggers>
</Style>
</UserControl.Style>
<Grid Background="Transparent">
<Border Name="border"
CornerRadius="10"
Margin="10"
BorderThickness="1"
BorderBrush="{DynamicResource Accent}">
<Border.Background>
<SolidColorBrush Color="{DynamicResource WindowBackgroundColor}" />
</Border.Background>
<Border.Resources>
<Storyboard x:Key="BackgroundAnimation">
<ColorAnimation Storyboard.TargetName="WindowBorderBackground"
Storyboard.TargetProperty="Color"
To="{DynamicResource WindowBackgroundColor}" Duration="0:0:.6" />
</Storyboard>
</Border.Resources>
<Border.Effect>
<DropShadowEffect ShadowDepth="0" Opacity="0.8" BlurRadius="10"/>
</Border.Effect>
<Grid Height="160" Width="300" Margin="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2" Source="/Resources/Images/newMail.png"
Margin="4" Width="80"></Image>
<TextBlock Text="{Binding Path=Title}"
TextOptions.TextRenderingMode="ClearType"
TextOptions.TextFormattingMode="Display"
Foreground="DimGray" TextAlignment="Center"
FontFamily="Arial"
FontSize="14" FontWeight="Bold"
VerticalAlignment="Center" Margin="4,4,4,2"
TextWrapping="Wrap" TextTrimming="CharacterEllipsis"
Grid.ColumnSpan="2" />
<Button x:Name="CloseButton"
Grid.Column="1"
HorizontalAlignment="Right"
Margin="0,0,27,0"
Click="CloseButton_Click"
Style="{StaticResource SystemCloseButton}"
Width="16"
Height="16" >
<Button.Content>
<Grid Width="10" Height="12"
RenderTransform="1,0,0,1,0,1">
<Path Data="M0,0 L8,7 M8,0 L0,7 Z"
Width="8" Height="7" VerticalAlignment="Center"
HorizontalAlignment="Center"
Stroke="{Binding Foreground,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Button}}" StrokeThickness="1.5" />
</Grid>
</Button.Content>
</Button>
<StackPanel Orientation="Vertical" Grid.Row="1"
Grid.Column="1" VerticalAlignment="Stretch">
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock Text="From :" HorizontalAlignment="Left"
VerticalAlignment="Top" FontWeight="Black"
Foreground="DarkGoldenrod"></TextBlock>
<TextBlock Grid.Row="0"
Grid.Column="1"
Text="{Binding Sender}"
TextTrimming="CharacterEllipsis"
TextWrapping="Wrap"
FontFamily="Arial"
VerticalAlignment="Center"
Foreground="Black"
Margin="5,0,0,0"
Width="145"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Margin="5">
<TextBlock Grid.Row="1"
Grid.Column="0" Grid.ColumnSpan="2"
Text="{Binding Content}"
TextTrimming="CharacterEllipsis"
TextWrapping="Wrap"
FontFamily="Arial"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
Foreground="Black"
Margin="5,0,0,0"
Width="150"/>
</StackPanel>
</StackPanel>
</Grid>
</Border>
</Grid>
</UserControl>
We need to add on click
event of the close button in the NotificationItem.xaml.cs,
to immediately close the notification window before the display duration elapsed.
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Window parentWindow = Window.GetWindow(this);
this.Visibility = Visibility.Hidden;
parentWindow.Close();
}
Step 3
Create resource dictionary file, e.g. MailNotificationUI.xaml, add dataTemplate
to define the presentation of your notification data and you must give it name e.g. x:Key="MailNotificationTemplate"
, as we will need this name when creating the NotificationConfiguration
object.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Model="clr-namespace:WPFNotificationDemo.Model"
xmlns:NotificationView="clr-namespace:WPFNotificationDemo.Assets">
<DataTemplate x:Key="MailNotificationTemplate"
DataType="{x:Type Model:MailNotification}">
<NotificationView:NotificationItem/>
</DataTemplate>
</ResourceDictionary>
Step 4
Modify App.xaml and add the MailNotificationUI.xaml resource dictionary reference:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source=
"/WPFNotification;component/Assets/NotificationUI.xaml" />
<ResourceDictionary Source=
"/Assets/MailNotificationUI.xaml" />
</ResourceDictionary.MergedDictionaries>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" />
</ResourceDictionary>
</Application.Resources>
Step 5
Display the mail notification:
- If you are using MVVM pattern, you need to do the following steps:
- Register the
INotificationDialogService
into your IOC container.
SimpleIoc.Default.Register<INotificationDialogService, NotificationDialogService>();
- Inject
INotificationDialogService
into your viewModel
. - Create
NotificationConfiguration
object with TemplateName
equal to the name of your dataTemplate
, remember what we said in step 3. - Finally call the
ShowNotificationWindow
method with notification
object and configuration
object.
public class MainViewModel : ViewModelBase
{
private readonly INotificationDialogService _dailogService;
public MainViewModel(INotificationDialogService dailogService)
{
_dailogService = dailogService;
}
private RelayCommand _mailNotification;
public RelayCommand MailNotification
{
get
{
return _mailNotification
?? (_mailNotification = new RelayCommand(
() =>
{
var newNotification = new MailNotification()
{
Title = "Vacation Request",
Sender = "Mohamed Magdy",
Content = "I would like to request for vacation
from 20/12/2015 to 30/12/2015 ............."
};
var configuration = new NotificationConfiguration(TimeSpan.Zero, null,
null,Constants.MailNotificationTemplateName);
_dailogService.ShowNotificationWindow(newNotification, configuration);
}));
}
}
}
Note:
To chnage notification flow direction. You have to set NotificationFlowDirection
property (default value is RightBottom) in Configuration
object and pass it to ShowNotificationWindow
method.
When any property of the configuration object is set to null
, it will use the default value except the displayDuration
property must be TimeSpan.Zero
to use the default value (2 seconds).
var configuration = new NotificationConfiguration(TimeSpan.Zero, null,
null, Constants.MailNotificationTemplateName,
NotificationFlowDirection.LeftUp);
_dailogService.ShowNotificationWindow(newNotification, configuration);
- If you are using Code-Behind, you need to do the following steps:
- Create
INotificationDialogService
object. - Create
MailNotification
object. - Create
NotificationConfiguration
object with TemplateName
equal to the name of your dataTemplate
, remember what we said in step 3.. - Finally, call the
ShowNotificationWindow
method with notification
object and configuration
object.
private void Button_Click(object sender, RoutedEventArgs e)
{
INotificationDialogService _dailogService = new NotificationDialogService();
var newNotification = new MailNotification()
{
Title = "Vacation Request",
Sender = "Mohamed Magdy",
Content = "I would like to request for vacation from 20/12/2015
to 30/12/2015 ............."
};
var configuration = new NotificationConfiguration(TimeSpan.Zero, null,
null, Constants.MailNotificationTemplateName);
_dailogService.ShowNotificationWindow(newNotification, configuration);
}
Now, you should see the mail notification on your screen like the figure below:
![](http://www.codeproject.com/KB/WPF/1073989/MailNotification.png)
In some situations we need to clear all notifications, for example, after closing the application we didn't need notifications to continue displayed on the screen, So to clear all notifications in the buffer list, You have to call ClearNotifications
method in NotificationDialogService
class
public class ViewModelLocator {
.
.
.
public static void Cleanup()
{
var notificationService = ServiceLocator.Current.GetInstance<INotificationDialogService>();
notificationService.ClearNotifications();
App.Current.Shutdown();
}
}
History
- 24 Jan 2016 original Post
- 12 Feb 2016 Add a link to the WPFToastNotification - A Deep Dive article.
- 28 Jun 2016 Add new features :
- Adds support for windows 7 or later
- Adds support for displaying notification on different screen resolutions
- Add notification Flow Direction
- Allow Remove All notifications in the buffer list