news 2026/7/4 5:23:08

扩展ToastNotifications:创建自定义通知类型与显示模板的完整教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
扩展ToastNotifications:创建自定义通知类型与显示模板的完整教程

扩展ToastNotifications:创建自定义通知类型与显示模板的完整教程

【免费下载链接】ToastNotificationsToast notifications for WPF allows you to create and display rich notifications in WPF applications. It's highly configurable with set of built-in options like positions, behaviours, themes and many others. It's extendable, it gives you possibility to create custom and interactive notifications in simply manner.项目地址: https://gitcode.com/gh_mirrors/to/ToastNotifications

ToastNotifications是一个功能强大的WPF通知库,它允许您在WPF应用程序中创建和显示丰富的通知。这个开源项目的核心优势在于其高度可扩展性,让开发者能够轻松创建自定义和交互式通知。在本终极指南中,我将向您展示如何充分利用ToastNotifications的扩展能力,创建完全自定义的通知类型和显示模板。🎯

为什么需要自定义Toast通知?

WPF应用程序中的通知系统对于用户体验至关重要。虽然ToastNotifications提供了内置的消息类型(如成功、错误、警告和信息),但在实际项目中,您可能需要更复杂的通知格式。比如:

  • 带有确认/取消按钮的交互式通知
  • 包含输入框的表单通知
  • 自定义布局和样式的品牌化通知
  • 集成第三方UI库(如MahApps.Metro)的通知

ToastNotifications的插件架构让这一切变得简单!✨

开始之前:项目准备

首先,您需要安装ToastNotifications核心包。打开NuGet包管理器控制台,运行以下命令:

Install-Package ToastNotifications

如果您还需要预定义的消息类型,可以同时安装:

Install-Package ToastNotifications.Messages

第一步:理解ToastNotifications的架构

ToastNotifications v2采用了清晰的分离架构:

  1. NotificationBase- 所有通知的基类,包含通知数据
  2. NotificationDisplayPart- 显示部分,控制通知的外观
  3. Notifier- 通知管理器,负责显示和生命周期管理

自定义通知的关键在于创建这两个组件的子类。让我们从最简单的自定义消息开始!

第二步:创建基础自定义通知类

在您的项目中创建一个新的C#类文件,比如CustomMessageNotification.cs。这个类将继承自NotificationBase并实现INotifyPropertyChanged接口:

using System.ComponentModel; using System.Runtime.CompilerServices; using ToastNotifications.Core; namespace YourApp.CustomNotifications { public class CustomMessageNotification : NotificationBase, INotifyPropertyChanged { private CustomMessageDisplayPart _displayPart; public override NotificationDisplayPart DisplayPart => _displayPart ?? (_displayPart = new CustomMessageDisplayPart(this)); public CustomMessageNotification(string title, string message, MessageOptions messageOptions) : base(message, messageOptions) { Title = title; Message = message; } private string _title; public string Title { get => _title; set { _title = value; OnPropertyChanged(); } } private string _message; public string Message { get => _message; set { _message = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }

这个类包含了通知的核心数据:标题和消息内容。DisplayPart属性返回将用于显示此通知的UI组件。

第三步:设计自定义显示模板

现在创建显示部分。在WPF中,这通常是一个用户控件。右键单击项目,选择"添加"→"用户控件",命名为CustomMessageDisplayPart.xaml

首先修改XAML文件,将基类从UserControl改为NotificationDisplayPart

<core:NotificationDisplayPart x:Class="YourApp.CustomNotifications.CustomMessageDisplayPart" 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:local="clr-namespace:YourApp.CustomNotifications" xmlns:core="clr-namespace:ToastNotifications.Core;assembly=ToastNotifications" mc:Ignorable="d" d:DesignHeight="80" d:DesignWidth="300" Background="#FF2D2D30" CornerRadius="5"> <Border BorderBrush="#FF007ACC" BorderThickness="2" CornerRadius="5"> <Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <TextBlock Text="{Binding Title}" FontWeight="Bold" FontSize="14" Foreground="#FF007ACC" Margin="0,0,0,5"/> <TextBlock Grid.Row="1" Text="{Binding Message}" FontWeight="Light" Foreground="White" TextWrapping="Wrap"/> </Grid> </Border> </core:NotificationDisplayPart>

然后修改代码隐藏文件:

using ToastNotifications.Core; namespace YourApp.CustomNotifications { public partial class CustomMessageDisplayPart : NotificationDisplayPart { public CustomMessageDisplayPart(CustomMessageNotification notification) { InitializeComponent(); Bind(notification); } } }

注意构造函数中的Bind(notification)调用,这是将通知数据绑定到UI的关键步骤!🔗

第四步:创建扩展方法(可选但推荐)

为了让使用更简洁,创建一个扩展方法:

using ToastNotifications; namespace YourApp.CustomNotifications { public static class CustomMessageExtensions { public static void ShowCustomMessage(this Notifier notifier, string title, string message) { notifier.Notify<CustomMessageNotification>(() => new CustomMessageNotification(title, message, new MessageOptions())); } } }

现在您可以使用更简洁的语法显示自定义通知:

notifier.ShowCustomMessage("操作成功", "您的文件已成功上传!");

第五步:创建交互式通知(带按钮)

让我们创建一个更高级的示例 - 带有确认和取消按钮的通知:

using System; using System.ComponentModel; using System.Runtime.CompilerServices; using System.Windows.Input; using ToastNotifications.Core; using YourApp.Utilities; // 假设您有RelayCommand类 namespace YourApp.CustomNotifications { public class ConfirmationNotification : NotificationBase, INotifyPropertyChanged { private ConfirmationDisplayPart _displayPart; private Action<ConfirmationNotification> _confirmAction; private Action<ConfirmationNotification> _cancelAction; public ICommand ConfirmCommand { get; set; } public ICommand CancelCommand { get; set; } public ConfirmationNotification(string message, Action<ConfirmationNotification> confirmAction, Action<ConfirmationNotification> cancelAction, MessageOptions messageOptions) : base(message, messageOptions) { Message = message; _confirmAction = confirmAction; _cancelAction = cancelAction; ConfirmCommand = new RelayCommand(x => _confirmAction(this)); CancelCommand = new RelayCommand(x => _cancelAction(this)); } public override NotificationDisplayPart DisplayPart => _displayPart ?? (_displayPart = new ConfirmationDisplayPart(this)); private string _message; public string Message { get => _message; set { _message = value; OnPropertyChanged(); } } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } }

对应的显示模板:

<core:NotificationDisplayPart x:Class="YourApp.CustomNotifications.ConfirmationDisplayPart" 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:local="clr-namespace:YourApp.CustomNotifications" xmlns:core="clr-namespace:ToastNotifications.Core;assembly=ToastNotifications" mc:Ignorable="d" d:DesignHeight="120" d:DesignWidth="350" Background="#FF2D2D30" CornerRadius="5"> <Border BorderBrush="#FFD84315" BorderThickness="2" CornerRadius="5"> <Grid Margin="15"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <TextBlock Text="确认操作" FontWeight="Bold" FontSize="14" Foreground="#FFD84315" Margin="0,0,0,10"/> <TextBlock Grid.Row="1" Text="{Binding Message}" FontWeight="Light" Foreground="White" TextWrapping="Wrap" Margin="0,0,0,15"/> <StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right"> <Button Content="取消" Command="{Binding CancelCommand}" Margin="0,0,10,0" Padding="12,6" Background="#FF757575" Foreground="White"/> <Button Content="确认" Command="{Binding ConfirmCommand}" Padding="12,6" Background="#FFD84315" Foreground="White"/> </StackPanel> </Grid> </Border> </core:NotificationDisplayPart>

第六步:集成第三方UI库(MahApps.Metro示例)

如果您使用MahApps.Metro,可以轻松集成其样式:

using MahApps.Metro.Controls; using ToastNotifications.Core; namespace YourApp.CustomNotifications { public partial class MetroNotificationDisplayPart : NotificationDisplayPart { public MetroNotificationDisplayPart(MetroNotification notification) { InitializeComponent(); Bind(notification); } } }

XAML中使用MahApps控件:

<core:NotificationDisplayPart x:Class="YourApp.CustomNotifications.MetroNotificationDisplayPart" 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:local="clr-namespace:YourApp.CustomNotifications" xmlns:core="clr-namespace:ToastNotifications.Core;assembly=ToastNotifications" xmlns:controls="http://metro.mahapps.com/winfx/xaml/controls" mc:Ignorable="d" d:DesignHeight="100" d:DesignWidth="350"> <controls:MetroWindow.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </controls:MetroWindow.Resources> <Grid> <controls:Tile Title="{Binding Title}" Content="{Binding Message}" Width="350" Height="100" HorizontalTitleAlignment="Center" VerticalTitleAlignment="Center" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/> </Grid> </core:NotificationDisplayPart>

第七步:配置和使用Notifier

在主应用程序中配置Notifier:

using ToastNotifications; using ToastNotifications.Lifetime; using ToastNotifications.Position; using System.Windows; namespace YourApp { public partial class MainWindow : Window { private Notifier _notifier; public MainWindow() { InitializeComponent(); InitializeNotifier(); } private void InitializeNotifier() { _notifier = new Notifier(cfg => { cfg.PositionProvider = new WindowPositionProvider( parentWindow: Application.Current.MainWindow, corner: Corner.BottomRight, offsetX: 10, offsetY: 10); cfg.LifetimeSupervisor = new TimeAndCountBasedLifetimeSupervisor( notificationLifetime: TimeSpan.FromSeconds(5), maximumNotificationCount: MaximumNotificationCount.FromCount(10)); cfg.Dispatcher = Application.Current.Dispatcher; }); } private void ShowCustomNotification_Click(object sender, RoutedEventArgs e) { // 使用自定义消息 _notifier.ShowCustomMessage("系统通知", "操作已完成!"); // 或者使用交互式通知 _notifier.Notify<ConfirmationNotification>(() => new ConfirmationNotification( "确定要删除这个文件吗?", notification => { // 确认操作 MessageBox.Show("文件已删除"); _notifier.Hide(notification); }, notification => { // 取消操作 _notifier.Hide(notification); }, new MessageOptions())); } protected override void OnClosed(EventArgs e) { _notifier?.Dispose(); base.OnClosed(e); } } }

最佳实践和高级技巧

1. 主题和样式统一

确保自定义通知与应用程序的整体设计语言保持一致。您可以在App.xaml中定义全局样式:

<Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <ResourceDictionary Source="pack://application:,,,/ToastNotifications.Messages;component/Themes/Default.xaml" /> <!-- 您的自定义样式 --> </ResourceDictionary.MergedDictionaries> <!-- 自定义通知样式 --> <Style TargetType="local:CustomMessageDisplayPart"> <Setter Property="Background" Value="{DynamicResource PrimaryBackground}" /> <Setter Property="Foreground" Value="{DynamicResource PrimaryForeground}" /> </Style> </ResourceDictionary> </Application.Resources>

2. 动画效果增强

为通知添加平滑的显示/隐藏动画:

<core:NotificationDisplayPart.Resources> <Storyboard x:Key="ShowAnimation"> <DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.3"/> <ThicknessAnimation Storyboard.TargetProperty="Margin" From="0,20,0,0" To="0" Duration="0:0:0.3"/> </Storyboard> <Storyboard x:Key="HideAnimation"> <DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="0:0:0.3"/> </Storyboard> </core:NotificationDisplayPart.Resources>

3. 响应式设计

确保通知在不同屏幕尺寸下都能良好显示:

<VisualStateManager.VisualStateGroups> <VisualStateGroup> <VisualState x:Name="Normal"> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="0"/> </VisualState.StateTriggers> <VisualState.Setters> <Setter TargetName="ContentGrid" Property="Width" Value="300"/> </VisualState.Setters> </VisualState> <VisualState x:Name="Wide"> <VisualState.StateTriggers> <AdaptiveTrigger MinWindowWidth="800"/> </VisualState.StateTriggers> <VisualState.Setters> <Setter TargetName="ContentGrid" Property="Width" Value="400"/> </VisualState.Setters> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups>

4. 性能优化

  • 使用VirtualizingStackPanel处理大量通知
  • 实现IDisposable接口及时释放资源
  • 使用弱引用避免内存泄漏

调试和故障排除

常见问题:

  1. 通知不显示

    • 检查Dispatcher是否正确设置
    • 确认PositionProvider配置正确
    • 验证通知生命周期设置
  2. 数据绑定失败

    • 确保通知类实现INotifyPropertyChanged
    • 检查XAML中的绑定路径是否正确
    • 确认Bind(notification)在构造函数中被调用
  3. 样式不生效

    • 检查资源字典引用
    • 确认样式选择器正确
    • 验证合并的资源字典顺序

调试技巧:

  • 使用SnoopLive Visual Tree检查WPF可视化树
  • 在通知构造函数中添加日志记录
  • 使用PresentationTraceSources.TraceLevel调试数据绑定

总结

通过ToastNotifications的扩展机制,您可以创建几乎任何类型的通知。从简单的文本通知到复杂的交互式表单,ToastNotifications提供了强大而灵活的框架。关键步骤包括:

  1. 创建继承自NotificationBase的通知数据类
  2. 创建继承自NotificationDisplayPart的显示模板
  3. 实现数据绑定和属性通知
  4. 创建扩展方法简化使用
  5. 配置Notifier实例

ToastNotifications的模块化设计让扩展变得直观而强大。无论是简单的状态通知还是复杂的用户交互,您都可以构建出符合应用程序需求的完美通知系统。🚀

记住,良好的通知系统不仅能提供信息,还能增强用户体验。花时间设计美观、一致且有用的通知,您的用户会感谢您的!

现在,开始创建您自己的自定义Toast通知吧!如果您遇到任何问题,可以参考项目中的示例代码:Src/Examples/CustomNotificationsExample/ 获取更多灵感。💡

【免费下载链接】ToastNotificationsToast notifications for WPF allows you to create and display rich notifications in WPF applications. It's highly configurable with set of built-in options like positions, behaviours, themes and many others. It's extendable, it gives you possibility to create custom and interactive notifications in simply manner.项目地址: https://gitcode.com/gh_mirrors/to/ToastNotifications

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/4 5:22:31

Ovine开发常见问题解答:新手必看的20个知识点

Ovine开发常见问题解答&#xff1a;新手必看的20个知识点 【免费下载链接】ovine Build entirety admin system ui blazing fast with json. 项目地址: https://gitcode.com/gh_mirrors/ov/ovine 你是否正在寻找一种快速构建管理系统的解决方案&#xff1f;Ovine框架正…

作者头像 李华
网站建设 2026/7/4 5:21:53

E-Hentai Downloader终极指南:2025年免费批量下载图库神器

E-Hentai Downloader终极指南&#xff1a;2025年免费批量下载图库神器 E-Hentai Downloader是一款功能强大的浏览器脚本工具&#xff0c;专门为E-Hentai和ExHentai用户设计的批量下载神器。这款免费工具能够智能识别图库内容&#xff0c;一键打包下载整个图集为zip文件&#x…

作者头像 李华
网站建设 2026/7/4 5:21:41

E-Hentai漫画下载神器:告别手动保存的终极指南

E-Hentai漫画下载神器&#xff1a;告别手动保存的终极指南 E-Hentai Downloader是一款专为漫画爱好者设计的浏览器脚本工具&#xff0c;能够智能识别E-Hentai和ExHentai平台上的漫画页面&#xff0c;一键生成ZIP格式的完整漫画存档。这款下载神器让你彻底告别繁琐的图片保存操作…

作者头像 李华
网站建设 2026/7/4 5:20:49

Enclave CLI工具完全指南:从安装到部署的完整工作流程

Enclave CLI工具完全指南&#xff1a;从安装到部署的完整工作流程 【免费下载链接】enclave A simpler way to compile React applications http://enclave.js.org 项目地址: https://gitcode.com/gh_mirrors/en/enclave Enclave是一个简化React应用编译流程的CLI工具&a…

作者头像 李华
网站建设 2026/7/4 5:20:10

E-Hentai漫画批量下载器:高效自动化收藏方案

E-Hentai漫画批量下载器&#xff1a;高效自动化收藏方案 还在为手动保存漫画页面而烦恼吗&#xff1f;E-Hentai下载器正是你需要的解决方案。这款自动化工具能够智能识别漫画画廊&#xff0c;一键打包下载整个专辑&#xff0c;彻底告别繁琐的图片保存操作。无论你是漫画收藏爱好…

作者头像 李华