在 Avalonia 中实现自定义 MessageBox,核心是封装一个可复用的对话框服务(Dialog Service),不依赖原生系统弹窗,而是基于 Avalonia 的
Window或
ContentDialog(需注意:Avalonia 当前稳定版暂无内置
ContentDialog,推荐用独立窗口方式)。关键在于解耦 UI 与业务逻辑,支持异步调用、主题适配、按钮定制和样式统一。
1. 创建自定义 MessageBox 窗口
新建一个继承自
Window的类(如
MessageBoxWindow.xaml),用于承载对话框 UI: 设置
WindowStyle="None"和
CanResize="False"获得更接近传统 MessageBox 的外观 使用
Grid布局,包含图标区、标题栏、消息文本、按钮容器;图标可用
Image或
PathIcon,支持根据类型(Info/Warning/Error)动态切换 为按钮绑定命令(如
OkCommand,
CancelCommand),通过
DataContext传递回调逻辑 添加阴影、圆角、动画(如
Transitions)提升视觉体验
2. 定义消息框数据模型与结果枚举
声明清晰的输入输出契约,便于类型安全调用:
定义
MessageBoxOptions类,包含:
-
string Message
-
string Title
-
MessageBoxButtons Buttons = MessageBoxButtons.OK(自定义枚举:OK / OKCancel / YesNo / YesNoCancel)
-
MessageBoxIcon Icon = MessageBoxIcon.None(自定义枚举:Information / Warning / Error / Question)
-
string OkText = "确定"(支持多语言)
-
string CancelText = "取消"
返回值使用
Task<messageboxresult></messageboxresult>,其中
MessageBoxResult是类似 WinForms 的枚举(OK / Cancel / Yes / No / None)。
3. 实现对话框服务接口与默认实现
定义接口
IFileDialogService不适用,应命名为
IMessageBoxService:
注意:不要在 ViewModel 中直接 new Window,而应通过服务注入。
接口方法示例:Task<messageboxresult> ShowAsync(MessageBoxOptions options, Window? owner = null)</messageboxresult>实现类(如
MessageBoxService)中,创建
MessageBoxWindow实例,设置
DataContext为包装后的视图模型(或直接传参绑定) 调用
window.ShowDialog(owner)(模态)或
window.Show(owner)(非模态),返回对应
Task支持传入
owner参数以实现窗口层级关系(如居中于主窗口)
4. 在 ViewModel 中调用并处理结果
使用 DI 注入服务,在需要处异步调用:
示例(C#):
var result = await _messageBoxService.ShowAsync(new MessageBoxOptions
{
Message = "确定要删除选中的文件吗?",
Title = "确认删除",
Buttons = MessageBoxButtons.YesNo,
Icon = MessageBoxIcon.Warning,
YesText = "删除",
NoText = "保留"
});
<p>if (result == MessageBoxResult.Yes)
{
// 执行删除逻辑
}
这样既保持 MVVM 洁净,又避免阻塞主线程,同时支持 await 后续操作。
