H.Test.Message-消息弹窗
·
H.Test.Message 示例项目学习教程
一、概述
H.Test.Message 是 WPF-Control 框架的消息系统示例项目,展示了如何使用框架提供的各种消息服务,包括:
- 对话框消息(Dialog)
- 通知消息(Notice)
- 轻提示消息(Snack)
- 表单消息(Form)
核心价值:通过统一的
IocMessage服务,一行代码实现各种消息提示,无需手动创建窗口。
二、项目结构
H.Test.Message/
├── App.xaml # 应用入口(XAML)
├── App.xaml.cs # 应用入口(代码)
├── MainWindow.xaml # 主窗口(XAML)
├── MainWindow.xaml.cs # 主窗口代码
└── H.Test.Message.csproj
三、核心文件解析
3.1 App.xaml.cs
public partial class App : ApplicationBase
{
protected override void ConfigureServices(IServiceCollection services)
{
// 注册对话框消息服务
services.AddSingleton<IDialogMessageService, AdornerDialogMessageService>();
// 注册表单消息服务
services.AddSingleton<IFormMessageService, FormMessageService>();
// 注册通知消息服务
services.AddNoticeMessage();
// 注册轻提示消息服务
services.AddSnackMessage();
// 注册关于模块
services.AddAbout();
}
protected override Window CreateMainWindow(StartupEventArgs e)
{
return new MainWindow();
}
}
关键服务:
| 服务 | 接口 | 实现 | 功能 |
|---|---|---|---|
| 对话框 | IDialogMessageService |
AdornerDialogMessageService |
模态对话框 |
| 表单 | IFormMessageService |
FormMessageService |
表单编辑对话框 |
| 通知 | - | NoticeMessage |
右上角通知 |
| 轻提示 | - | SnackMessage |
底部轻提示 |
3.2 MainWindow.xaml
<Window x:Class="H.Test.Message.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:h="https://github.com/HeBianGu"
Title="MainWindow" Width="800" Height="450"
Style="{StaticResource {x:Static WindowKeys.Default}}">
<TabControl>
<!-- Dialog 标签页 -->
<TabItem Header="Dialog">
<UniformGrid>
<!-- 显示 IOC 注册的 Presenter -->
<Button Command="{ShowIocCommand Type={x:Type IAboutViewPresenter}}"
Content="ShowIocCommand" />
<!-- 显示消息对话框 -->
<Button Command="{ShowMessageCommand Message=我是消息,Name=我是标题}"
Content="ShowMessageCommand" />
<!-- 显示 Presenter -->
<Button Command="{ShowCommand Presnter={h:GetStudent}}"
Content="ShowCommand" />
<!-- 显示进度对话框 -->
<Button Command="{ShowPercentCommand}"
Content="ShowPercentCommand" />
<!-- 显示字符串对话框 -->
<Button Command="{ShowStringCommand}"
Content="ShowStringCommand" />
<!-- 显示等待对话框 -->
<Button Command="{ShowWaitCommand}"
Content="ShowWaitCommand" />
<!-- 显示编辑对话框 -->
<Button Command="{ShowEditCommand Value={h:GetStudent}}"
Content="ShowEditCommand" />
<!-- 显示标签页编辑对话框 -->
<Button Command="{ShowTabEditCommand Value={h:GetStudent}}"
Content="ShowTabEditCommand" />
<!-- 显示查看对话框 -->
<Button Command="{ShowViewCommand Value={h:GetStudent}}"
Content="ShowViewCommand" />
<!-- 内嵌弹窗 -->
<Button Command="{h:ShowAdornerDialogCommand}"
CommandParameter="{h:GetStudent}"
Content="内嵌弹窗" />
</UniformGrid>
</TabItem>
<!-- Notice 标签页 -->
<TabItem Header="Notice">
<UniformGrid>
<Button Command="{h:ShowInfoNoticeMessageCommand Message=我是 Info 消息}"
Content="ShowInfo" />
<Button Command="{h:ShowErrorNoticeMessageCommand Message=我是 Error 消息}"
Content="ShowError" />
<Button Command="{h:ShowSuccessNoticeMessageCommand Message=我是 Success 消息}"
Content="ShowSuccess" />
<Button Command="{h:ShowWarnNoticeMessageCommand Message=我是 Warn 消息}"
Content="ShowWarn" />
<Button Command="{h:ShowFatalNoticeMessageCommand Message=我是 Fatal 消息}"
Content="ShowFatal" />
<Button Command="{h:ShowProgressNoticeMessageCommand Message=我是 Progress 消息}"
Content="ShowProgress" />
</UniformGrid>
</TabItem>
<!-- Snack 标签页 -->
<TabItem Header="Snack">
<UniformGrid>
<Button Command="{h:ShowInfoSnackMessageCommand Message=我是 Info 消息}"
Content="ShowInfo" />
<Button Command="{h:ShowErrorSnackMessageCommand Message=我是 Error 消息}"
Content="ShowError" />
<Button Command="{h:ShowSuccessSnackMessageCommand Message=我是 Success 消息}"
Content="ShowSuccess" />
<Button Command="{h:ShowWarnSnackMessageCommand Message=我是 Warn 消息}"
Content="ShowWarn" />
<Button Command="{h:ShowFatalSnackMessageCommand Message=我是 Fatal 消息}"
Content="ShowFatal" />
<Button Command="{h:ShowProgressSnackMessageCommand Message=我是 Progress 消息}"
Content="ShowProgress" />
</UniformGrid>
</TabItem>
<!-- CommandMessage 标签页 -->
<TabItem Header="CommandMessage">
<UniformGrid>
<!-- 异步消息命令 -->
<Button Command="{h:AsyncMessageCommand Message=点击执行}"
Content="{Binding RelativeSource={RelativeSource Mode=Self},
Path=Command.Message}" />
<!-- 异步进度命令 -->
<Button Command="{h:AsyncPercentCommand Value=0.0}"
Content="{Binding RelativeSource={RelativeSource Mode=Self},
Path=Command.Value}" />
</UniformGrid>
</TabItem>
</TabControl>
</Window>
四、消息系统详解
4.1 IocMessage 统一入口
public static class IocMessage
{
// 对话框消息
public static IDialogMessageService Dialog { get; }
// 通知消息
public static INoticeMessageService Notice { get; }
// 轻提示消息
public static ISnackMessageService Snack { get; }
// 表单消息
public static IFormMessageService Form { get; }
// 窗口消息
public static IWindowMessageService Window { get; }
}
4.2 对话框消息(Dialog)
基本使用
// 显示简单消息
IocMessage.Dialog.ShowMessage("操作成功", "提示");
// 显示等待对话框
using (var wait = IocMessage.Dialog.ShowWait("正在加载..."))
{
// 执行耗时操作
await Task.Delay(2000);
}
// 显示百分比进度
IocMessage.Dialog.ShowPercent("正在处理", 0.5);
// 显示字符串对话框
IocMessage.Dialog.ShowString("这是一段文本", "标题");
显示 Presenter
// 显示 IOC 注册的 Presenter
IocMessage.Dialog.ShowIoc<IAboutViewPresenter>();
// 显示自定义 Presenter
var student = new Student { Name = "张三", Age = 25 };
IocMessage.Dialog.ShowCommand(student);
编辑对话框
// 显示编辑对话框
var student = new Student { Name = "张三", Age = 25 };
bool? result = await IocMessage.Dialog.ShowEdit(student);
if (result == true)
{
// 用户点击了确定
Console.WriteLine($"编辑后的数据:{student.Name}");
}
带验证的表单
var student = new Student();
student.Age = 200; // 不合法的年龄
// 带验证的编辑
Predicate<Student> match = x =>
{
if (x.Age > 100)
{
IocMessage.Dialog.Show("年龄输入不合法");
return false;
}
return true;
};
IocMessage.Form.ShowEdit(student, match);
4.3 通知消息(Notice)
基本类型
// Info 通知
IocMessage.Notice.ShowInfo("这是一条 Info 消息");
// Error 通知
IocMessage.Notice.ShowError("这是一条 Error 消息");
// Success 通知
IocMessage.Notice.ShowSuccess("这是一条 Success 消息");
// Warn 通知
IocMessage.Notice.ShowWarn("这是一条 Warn 消息");
// Fatal 通知
IocMessage.Notice.ShowFatal("这是一条 Fatal 消息");
进度通知
// 进度通知
IocMessage.Notice.ShowProgress("正在处理...", 0.5);
字符串通知
// 字符串通知
IocMessage.Notice.ShowString("自定义通知内容");
对话框通知
// 对话框通知
IocMessage.Notice.ShowDialog("需要用户确认的消息");
4.4 轻提示消息(Snack)
基本类型
// Info 轻提示
IocMessage.Snack.ShowInfo("这是一条 Info 消息");
// Error 轻提示
IocMessage.Snack.ShowError("这是一条 Error 消息");
// Success 轻提示
IocMessage.Snack.ShowSuccess("操作成功!");
// Warn 轻提示
IocMessage.Snack.ShowWarn("这是一条 Warn 消息");
// Fatal 轻提示
IocMessage.Snack.ShowFatal("这是一条 Fatal 消息");
进度轻提示
// 进度轻提示
IocMessage.Snack.ShowProgress("正在下载...", 0.75);
字符串轻提示
// 字符串轻提示
IocMessage.Snack.ShowString("自定义轻提示内容");
4.5 异步命令
异步消息命令
// 在 ViewModel 中使用
public ICommand AsyncMessageCommand { get; }
public MyViewModel()
{
AsyncMessageCommand = new AsyncMessageCommand("点击执行");
}
异步进度命令
// 在 ViewModel 中使用
public ICommand AsyncPercentCommand { get; }
public MyViewModel()
{
AsyncPercentCommand = new AsyncPercentCommand(0.0);
}
五、命令系统
5.1 对话框命令
| 命令 | 功能 | 参数 |
|---|---|---|
ShowMessageCommand |
显示消息对话框 | Message, Name, Width, Height |
ShowPercentCommand |
显示进度对话框 | - |
ShowStringCommand |
显示字符串对话框 | - |
ShowWaitCommand |
显示等待对话框 | - |
ShowEditCommand |
显示编辑对话框 | Value |
ShowTabEditCommand |
显示标签页编辑对话框 | Value, TabNames |
ShowViewCommand |
显示查看对话框 | Value |
ShowIocCommand |
显示 IOC 注册的 Presenter | Type |
5.2 通知命令
| 命令 | 功能 | 参数 |
|---|---|---|
ShowInfoNoticeMessageCommand |
Info 通知 | Message |
ShowErrorNoticeMessageCommand |
Error 通知 | Message |
ShowSuccessNoticeMessageCommand |
Success 通知 | Message |
ShowWarnNoticeMessageCommand |
Warn 通知 | Message |
ShowFatalNoticeMessageCommand |
Fatal 通知 | Message |
ShowProgressNoticeMessageCommand |
进度通知 | Message, Value |
5.3 轻提示命令
| 命令 | 功能 | 参数 |
|---|---|---|
ShowInfoSnackMessageCommand |
Info 轻提示 | Message |
ShowErrorSnackMessageCommand |
Error 轻提示 | Message |
ShowSuccessSnackMessageCommand |
Success 轻提示 | Message |
ShowWarnSnackMessageCommand |
Warn 轻提示 | Message |
ShowFatalSnackMessageCommand |
Fatal 轻提示 | Message |
ShowProgressSnackMessageCommand |
进度轻提示 | Message, Value |
六、运行项目
6.1 步骤
1. 打开 Visual Studio 2022
2. 打开解决方案:Solution/WPF-Control.sln
3. 在解决方案资源管理器中找到 H.Test.Message 项目
4. 右键点击项目 → 设置为启动项目
5. 按 F5 运行
6.2 预期效果
运行后会看到:
- 一个包含 4 个标签页的窗口
- Dialog:各种对话框按钮
- Notice:通知消息按钮
- Snack:轻提示消息按钮
- CommandMessage:异步命令按钮
点击不同按钮会触发相应的消息提示。
七、实际应用案例
7.1 在 ViewModel 中使用
public class MainViewModel : Bindable
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; RaisePropertyChanged(); }
}
// 保存命令
public ICommand SaveCommand { get; }
public MainViewModel()
{
SaveCommand = new RelayCommand(async x => await SaveAsync());
}
private async Task SaveAsync()
{
// 显示等待提示
using (var wait = IocMessage.Dialog.ShowWait("正在保存..."))
{
try
{
// 模拟保存操作
await Task.Delay(2000);
// 保存成功
IocMessage.Snack.ShowSuccess("保存成功!");
}
catch (Exception ex)
{
// 保存失败
IocMessage.Notice.ShowError($"保存失败:{ex.Message}");
}
}
}
}
7.2 带验证的表单编辑
public class UserEditViewModel : Bindable
{
public ICommand EditUserCommand { get; }
public UserEditViewModel()
{
EditUserCommand = new RelayCommand(x => EditUser());
}
private void EditUser()
{
var user = new User
{
Name = "张三",
Email = "zhangsan@example.com",
Age = 25
};
// 带验证的编辑
Predicate<User> validator = u =>
{
if (string.IsNullOrEmpty(u.Name))
{
IocMessage.Dialog.ShowMessage("姓名不能为空", "验证失败");
return false;
}
if (u.Age < 0 || u.Age > 150)
{
IocMessage.Dialog.ShowMessage("年龄必须在 0-150 之间", "验证失败");
return false;
}
if (!u.Email.Contains("@"))
{
IocMessage.Dialog.ShowMessage("邮箱格式不正确", "验证失败");
return false;
}
return true;
};
bool? result = IocMessage.Form.ShowEdit(user, validator);
if (result == true)
{
IocMessage.Snack.ShowSuccess("用户信息更新成功!");
}
}
}
7.3 进度通知
public class DownloadViewModel : Bindable
{
public ICommand DownloadCommand { get; }
public DownloadViewModel()
{
DownloadCommand = new RelayCommand(async x => await DownloadAsync());
}
private async Task DownloadAsync()
{
// 显示进度对话框
using (var progress = IocMessage.Dialog.ShowPercent("正在下载...", 0))
{
for (int i = 0; i <= 100; i++)
{
// 模拟下载
await Task.Delay(100);
// 更新进度
progress.Update(i / 100.0);
// 同时发送通知
if (i % 10 == 0)
{
IocMessage.Notice.ShowProgress($"下载进度:{i}%", i / 100.0);
}
}
}
IocMessage.Snack.ShowSuccess("下载完成!");
}
}
八、消息类型对比
8.1 对话框 vs 通知 vs 轻提示
| 特性 | 对话框(Dialog) | 通知(Notice) | 轻提示(Snack) |
|---|---|---|---|
| 显示位置 | 窗口中央 | 右上角 | 底部中央 |
| 模态 | 是(阻塞操作) | 否 | 否 |
| 持续时间 | 用户关闭 | 自动消失(默认 3 秒) | 自动消失(默认 2 秒) |
| 适用场景 | 需要用户确认 | 重要通知 | 轻量提示 |
| 示例 | 确认删除、编辑表单 | 系统通知、错误提示 | 操作成功、加载中 |
8.2 选择建议
需要用户确认?
├─ 是 → 使用 Dialog(对话框)
│ ├─ 简单消息 → ShowMessage
│ ├─ 编辑数据 → ShowEdit
│ └─ 等待操作 → ShowWait
│
└─ 否 → 不需要用户确认
├─ 重要通知 → 使用 Notice(通知)
│ ├─ 错误 → ShowError
│ ├─ 成功 → ShowSuccess
│ └─ 进度 → ShowProgress
│
└─ 轻量提示 → 使用 Snack(轻提示)
├─ 操作反馈 → ShowSuccess
├─ 加载提示 → ShowWait
└─ 简单提示 → ShowInfo
九、常见问题
9.1 消息不显示
问题:调用消息服务后没有显示。
解决:
1. 确保已注册对应的消息服务
2. 检查 IOC 容器是否正确构建
3. 确认在主线程中调用(UI 线程)
9.2 对话框无法关闭
问题:对话框显示后无法关闭。
解决:
1. 使用 using 语句自动关闭
2. 手动调用 Close() 方法
3. 检查是否有未完成的异步操作
9.3 通知消息重叠
问题:多条通知消息重叠显示。
解决:
1. 框架会自动排队显示
2. 可以调整通知显示时间
3. 手动关闭旧通知再显示新通知
十、总结
通过学习 H.Test.Message,您掌握了 WPF-Control 的消息系统:
- 对话框消息:模态对话框,用于确认、编辑、等待
- 通知消息:右上角通知,用于重要提示
- 轻提示消息:底部轻提示,用于轻量反馈
- 表单消息:自动表单编辑对话框
- 命令系统:内置命令简化使用
关键要点:
- 使用
IocMessage统一访问所有消息服务 - 对话框适合需要用户确认的场景
- 通知适合重要提示
- 轻提示适合轻量反馈
- 内置命令可以在 XAML 中直接使用
最佳实践:
- 耗时操作使用
ShowWait显示等待提示 - 操作成功使用
Snack.ShowSuccess - 操作失败使用
Notice.ShowError - 需要确认使用
Dialog.ShowMessage
掌握这套消息系统,可以让您的应用交互更加专业和友好。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)