WPF 吐司通知






3.97/5 (14投票s)
WPF 应用程序的精美吐司通知,
只需下载项目演示,使用 Nuget 恢复丢失的包即可。
引言
适用于 WPF 应用程序的精美弹出通知,易于使用并支持 MVVM 模式。一个在屏幕底部显示带有图片、标题和内容的简短通知窗口。您可以使用默认实现或构建自己的自定义通知。
Github
您可以在 Github 上查看该项目 此处,下载源代码和应用演示,尽情享用。
演示展示了如何使用弹出通知,以默认实现或您自己的自定义实现方式显示它。
Nuget
WPF 弹出通知可在 NuGet 上找到,您可以使用 NuGet 管理器安装它,或在程序包管理器控制台中运行以下命令。
PM> Install-Package WPFNotification
注意: 在 WPF 弹出通知 - 深入探讨 文章中,我逐步解释了该程序包背后的代码。
在本文中,我们将演示
特点
- 简单、轻量级、精美的弹出通知,带有标题、内容和可覆盖的预定义图片,显示在屏幕底部。
- 支持 MVVM 模式。
- 支持 Windows 7 或更高版本。
- 支持在不同屏幕分辨率下显示通知。
- 可配置,您可以使用默认通知配置,或使用以下属性进行重新配置
- 显示时长
- 宽度
- 高度
- 通知模板
- 通知流方向,这决定了新通知窗口将如何出现。可用选项为
- 右下(默认)。
- 左下。
- 左上。
- 右上。
- 可定制
- 您可以实现自己的通知
- 一次显示一个通知,如果有其他通知,它们将排队等待,并在空间可用时显示。
- 当鼠标悬停在通知上时,阻止通知淡出。
- 允许清除通知列表和通知缓冲区列表中的所有通知
入门
添加通知程序集
- 打开 Visual Studio,打开一个现有的 WPF 应用程序或创建一个新的 WPF 应用程序项目。
- 获取最新的
WPFToastNotification
发布版本 并将其内容解压缩到磁盘,或使用 NuGet 安装 WPFNotification 程序包。 - 添加对 WPFNotification.dll 的程序集引用。
- 修改 App.xaml 并添加以下资源字典引用
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/WPFNotification;component/Assets/NotificationUI.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
注意
如果您使用 NuGet 安装 WPFNotification 程序包。它会自动添加程序集引用并为您修改 App.xaml 文件。
显示默认弹出通知
假设通知将在用户单击按钮时显示
- 如果您使用 MVVM 模式,您需要执行以下步骤
- 将
INotificationDialogService
注册到您的 IOC 容器中。我正在使用SimpleIOC
容器。
SimpleIoc.Default.Register<INotificationDialogService, NotificationDialogService>();
- 将
INotificationDialogService
注入到您的viewModel
中。 - 创建
Notification
对象,包含您的Title
、Message
和可选的ImgURL
(如果为null
,则会显示默认的预定义图片)。 - 最后,调用
ShowNotificationWindow
方法并传入通知对象。
public class MainViewModel : ViewModelBase { private readonly INotificationDialogService _dailogService; // inject INotificationDialogservice public MainViewModel(INotificationDialogService dailogService) { _dailogService = dailogService; } private RelayCommand _defaultNotification; /// <summary> /// The DefaultNotification command. /// Create Notification object and send it to NotificationDialogService /// to display the notification. /// </summary> public RelayCommand DefaultNotification { get { return _defaultNotification ?? (_defaultNotification = new RelayCommand( () => { // Create the notification object var newNotification = new Notification() { Title = "Machine error", Message = "Error!! Please check your Machine Code and Try Again" }; // call the ShowNotificationWindow Method with the notification object _dailogService.ShowNotificationWindow(newNotification); })); } } }
- 将
- 如果您使用代码隐藏,您需要执行以下步骤
- 创建
INotificationDialogService
对象。 - 创建
Notification
对象,包含您的Title
、Message
和可选的ImgURL
(如果为null
,则会显示默认的预定义图片)。 - 最后,调用
ShowNotificationWindow
方法并传入通知对象。
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); }
- 创建
现在您应该会在屏幕上看到通知,如下面的图所示
创建自定义通知
假设我们将创建一个邮件通知,该通知将在用户单击按钮时显示。
要创建自定义通知,我们需要执行五个步骤
步骤 1
创建自定义通知模型,例如 MailNotification
类,如下所示
public class MailNotification
{
public string Title { get; set; }
public string Sender { get; set; }
public string Content { get; set; }
}
注意
如果您想使用默认通知模型,但需要更改通知 UI,请忽略此步骤,直接从第 2 步开始。
第二步
创建自定义通知 UI,例如 NotificationItem.xaml(用户控件),并将其绑定到 MailNotification
模型,如下所示
<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>
我们需要在 NotificationItem.xaml.cs 中的关闭按钮上添加一个 click
事件,以便在显示时长结束之前立即关闭通知窗口。
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Window parentWindow = Window.GetWindow(this);
this.Visibility = Visibility.Hidden;
parentWindow.Close();
}
步骤 3
创建资源字典文件,例如 MailNotificationUI.xaml,添加 dataTemplate
来定义通知数据的表示形式,并且您必须为其命名,例如 x:Key="MailNotificationTemplate"
,因为我们在创建 NotificationConfiguration
对象时需要这个名称。
<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>
步骤 4
修改 App.xaml 并添加 MailNotificationUI.xaml 资源字典引用
<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>
步骤 5
显示邮件通知
- 如果您使用 MVVM 模式,您需要执行以下步骤
- 将
INotificationDialogService
注册到您的 IOC 容器中。
SimpleIoc.Default.Register<INotificationDialogService, NotificationDialogService>();
- 将
INotificationDialogService
注入到您的viewModel
中。 - 创建
NotificationConfiguration
对象,并将TemplateName
设置为您的dataTemplate
的名称,请记住我们在第 3 步中提到的内容。 - 最后调用
ShowNotificationWindow
方法,并传入notification
对象和configuration
对象。
public class MainViewModel : ViewModelBase { private readonly INotificationDialogService _dailogService; // inject INotificationDialogservice public MainViewModel(INotificationDialogService dailogService) { _dailogService = dailogService; } private RelayCommand _mailNotification; /// <summary> /// The MailNotification command. /// Create Notification and NotificationConfiguration objects, /// and send them to NotificationDialogService to display the notification. /// </summary> public RelayCommand MailNotification { get { return _mailNotification ?? (_mailNotification = new RelayCommand( () => { // create notification object 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 ............." }; // create configuration object var configuration = new NotificationConfiguration(TimeSpan.Zero, null, null,Constants.MailNotificationTemplateName); // call show method with notification and configuration objects _dailogService.ShowNotificationWindow(newNotification, configuration); })); } } }
注意
要更改通知流方向,您必须在
Configuration
对象中设置NotificationFlowDirection
属性(默认值为 RightBottom),然后将其传递给ShowNotificationWindow
方法。
当配置对象的任何属性设置为null
时,它将使用默认值,除了displayDuration
属性必须设置为TimeSpan.Zero
才能使用默认值(2 秒)。var configuration = new NotificationConfiguration(TimeSpan.Zero, null, null, Constants.MailNotificationTemplateName, NotificationFlowDirection.LeftUp); _dailogService.ShowNotificationWindow(newNotification, configuration);
- 将
- 如果您使用代码隐藏,您需要执行以下步骤
- 创建
INotificationDialogService
对象。 - 创建
MailNotification
对象。 - 创建
NotificationConfiguration
对象,并将TemplateName
设置为您的dataTemplate
的名称,请记住我们在第 3 步中提到的内容。 - 最后,调用
ShowNotificationWindow
方法,并传入notification
对象和configuration
对象。
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); }
- 创建
现在,您应该会在屏幕上看到邮件通知,如下面的图所示
清除通知
在某些情况下,我们需要清除所有通知,例如,在关闭 应用程序后,我们不需要通知继续显示 在 屏幕上。所以,要清除缓冲区列表中的所有通知,您必须在 NotificationDialogService
类中调用 ClearNotifications
方法。
public class ViewModelLocator {
.
.
.
public static void Cleanup()
{
var notificationService = ServiceLocator.Current.GetInstance<INotificationDialogService>();
notificationService.ClearNotifications();
App.Current.Shutdown();
}
}
历史
- 2016 年 1 月 24 日 原始帖子
- 2016 年 2 月 12 日 添加指向 WPFToastNotification - 深入探讨 文章的链接。
- 2016 年 6 月 28 日 添加新功能
- 支持 Windows 7 或更高版本
- 支持在不同屏幕分辨率下显示通知
- 添加通知流方向
- 允许删除缓冲区列表中的所有通知