11 KiB
Message 全局提示
概述
全局提示(Message)用于在页面顶部居中展示轻量级的操作反馈信息,属于非阻断性反馈组件。它在操作完成后自动出现在页面顶部,短暂停留后自动消失,不打断用户的操作流程。适用于表单提交成功/失败、异步操作状态提示、系统信息通知等场景。
AtomUI 的 Message 控件对标 Ant Design 5.0 Message 的设计规范,在 .NET / Avalonia 平台上提供一致的全局提示体验。
设计原理
Ant Design 的全局提示设计哲学
Ant Design 对全局提示的定位是:「全局展示操作反馈信息,居顶部居中显示并自动消失,是一种不打断用户操作的轻量级提示方式」。它与 Notification(通知提醒)的关键区别在于:
| 特性 | Message(全局提示) | Notification(通知提醒) |
|---|---|---|
| 位置 | 页面顶部居中 | 页面四角 |
| 内容量 | 仅文本,轻量单行 | 标题 + 详细描述 + 操作按钮 |
| 交互 | 无交互,自动消失 | 可关闭、可操作 |
| 适用场景 | 操作反馈(成功/失败/警告) | 需要用户关注的复杂通知 |
五种消息类型(对应不同操作结果和语义):
| 类型 | 图标 | 设计意图 | 典型用途 |
|---|---|---|---|
| ℹ️ Information | InfoCircleFilled(蓝色) |
普通信息提示,中性语义 | 一般性操作提示、说明信息 |
| ✅ Success | CheckCircleFilled(绿色) |
操作成功确认 | 表单提交成功、保存完成 |
| ⚠️ Warning | ExclamationCircleFilled(黄色) |
警告提示,需要注意 | 操作有风险但可继续 |
| ❌ Error | CloseCircleFilled(红色) |
操作失败,需要关注 | 提交失败、网络错误 |
| 🔄 Loading | LoadingOutlined(蓝色旋转) |
异步操作进行中 | 数据加载、文件上传中 |
AtomUI 的架构设计
AtomUI 的 Message 系统由三个核心组件协作完成:
WindowMessageManager(容器管理器)
├── 挂载在 TopLevel 的 AdornerLayer 上
├── 管理消息的生命周期(显示、自动关闭、最大数量控制)
└── MessageCard(单条消息卡片)× N
├── 图标(根据 MessageType 自动匹配)
├── 文本内容
└── 入场/出场动画(MoveUpIn / MoveUpOut)
职责分离:
IMessage/Message— 数据模型,承载消息内容、类型、过期时间等信息MessageCard— 视觉控件,负责单条消息的渲染和动画WindowMessageManager— 容器管理器,负责消息的创建、排布和生命周期管理
功能详解
消息类型(MessageType)
消息类型通过 MessageType 枚举指定,每种类型会自动匹配对应的图标和颜色:
| 类型 | 默认图标 | 图标颜色来源 |
|---|---|---|
Information |
InfoCircleFilled |
SharedToken.ColorPrimary(蓝色) |
Success |
CheckCircleFilled |
SharedToken.ColorSuccess(绿色) |
Warning |
ExclamationCircleFilled |
SharedToken.ColorWarning(黄色) |
Error |
CloseCircleFilled |
SharedToken.ColorError(红色) |
Loading |
LoadingOutlined(旋转) |
SharedToken.ColorPrimary(蓝色) |
自动关闭与过期时间
每条消息都有 Expiration 属性控制自动关闭时间:
- 默认值为 5 秒
- 设置为
TimeSpan.Zero时消息不会自动关闭,需要手动调用Close() - 过期后通过
DispatcherTimer.RunOnce触发关闭流程
最大显示数量
WindowMessageManager.MaxItems 控制同时可见的最大消息数量(默认为 5)。当新消息导致超出上限时,最早显示的消息会被自动关闭。
入场/出场动画
MessageCard 使用 MoveUpIn / MoveUpOut 动画实现消息的入场和出场效果:
- 入场:从上方滑入 + 透明度从 0 到 1,使用
CubicEaseOut缓动 - 出场:向上滑出 + 透明度从 1 到 0,使用
CubicEaseIn缓动 - 动画偏移量固定为 100px(
AnimationMaxOffsetY) - 动画时长由
SharedToken.MotionDurationMid控制 - 可通过
IsMotionEnabled = false禁用动画
关闭回调
通过 Message 构造函数的 onClose 参数传入关闭回调,当消息关闭(无论自动或手动)时执行。这支持链式消息——在一条消息关闭后立即显示下一条。
自定义图标
通过 Message 构造函数的 icon 参数可以传入自定义 PathIcon,覆盖默认的类型图标。
与 Ant Design 规范的对齐程度
| 特性 | Ant Design (React) | AtomUI (Avalonia) | 对齐情况 |
|---|---|---|---|
| 五种消息类型 | ✅ info / success / warning / error / loading |
✅ MessageType 枚举 |
✅ 完全对齐 |
| 顶部居中显示 | ✅ | ✅ HorizontalAlignment="Center" + VerticalAlignment="Top" |
✅ 完全对齐 |
| 自动关闭 | ✅ 默认 3 秒 | ✅ 默认 5 秒 | ⚠️ 默认时长不同 |
| 自定义图标 | ✅ icon 属性 |
✅ Icon 参数 |
✅ 对齐 |
| 关闭回调 | ✅ onClose |
✅ OnClose 回调 |
✅ 对齐 |
| Loading 类型 | ✅ | ✅ 旋转 LoadingOutlined 图标 |
✅ 完全对齐 |
| 自定义时长 | ✅ duration 参数 |
✅ Expiration 参数 |
✅ 对齐 |
| 最大显示数量 | ✅ maxCount |
✅ MaxItems 属性 |
✅ 对齐 |
| Promise 接口 | ✅ message.open().then(...) |
❌ 使用回调模式 | ⚠️ C# 无 Promise,使用 OnClose 回调 |
| 全局配置 | ✅ message.config() |
❌ 通过 WindowMessageManager 实例配置 |
⚠️ 实例级配置 vs 全局配置 |
| 更新消息内容 | ✅ 通过 key 更新 |
✅ Message.Content 支持 INotifyPropertyChanged |
⚠️ 机制不同但功能可实现 |
继承关系
MessageCard
Avalonia.Controls.Primitives.TemplatedControl
└── AtomUI.Desktop.Controls.MessageCard
└── implements IMotionAwareControl
WindowMessageManager
Avalonia.Controls.Primitives.TemplatedControl
└── AtomUI.Desktop.Controls.WindowMessageManager
├── implements IMessageManager
├── implements IMotionAwareControl
└── implements IDisposable
Message(数据模型)
AtomUI.Desktop.Controls.Message
├── implements IMessage
└── implements INotifyPropertyChanged
各层级职责划分:
| 层级 | 提供的能力 |
|---|---|
TemplatedControl |
模板化控件基础设施、OnApplyTemplate、CornerRadius 等 |
MessageCard |
单条消息的视觉呈现:图标自动匹配、伪类管理、入场/出场动画 |
WindowMessageManager |
消息容器管理:挂载到 TopLevel、消息排布、最大数量控制、自动关闭计时器 |
Message |
消息数据模型:内容、类型、过期时间、关闭回调 |
实现的接口:
| 接口 | 定义位置 | 控件 | 作用 |
|---|---|---|---|
IMessage |
AtomUI.Desktop.Controls |
数据模型 | 定义消息数据契约(Content、Type、Expiration、OnClose、Icon) |
IMessageManager |
AtomUI.Desktop.Controls |
WindowMessageManager | 定义消息管理器契约(Show 方法) |
IMotionAwareControl |
AtomUI.Controls |
MessageCard / WindowMessageManager | 支持动画启用/禁用控制 |
INotifyPropertyChanged |
System.ComponentModel |
Message | 支持属性变更通知(Content、Icon 可动态更新) |
IDisposable |
System |
WindowMessageManager | 支持资源释放(从 AdornerLayer 卸载、清理事件订阅) |
源码位置
| 层级 | 文件路径 | 说明 |
|---|---|---|
| 数据接口 | src/AtomUI.Desktop.Controls/Message/IMessage.cs |
IMessage 消息数据契约 |
| 管理器接口 | src/AtomUI.Desktop.Controls/Message/IMessageManager.cs |
IMessageManager 管理器契约 |
| 数据模型 | src/AtomUI.Desktop.Controls/Message/Message.cs |
Message 消息数据实现 |
| 消息卡片 | src/AtomUI.Desktop.Controls/Message/MessageCard.cs |
MessageCard 视觉控件 |
| 消息类型枚举 | src/AtomUI.Desktop.Controls/Message/MessageType.cs |
MessageType 枚举 |
| 伪类常量 | src/AtomUI.Desktop.Controls/Message/MessageCardPseudoClass.cs |
伪类常量定义 |
| 容器管理器 | src/AtomUI.Desktop.Controls/Message/WindowMessageManager.cs |
WindowMessageManager 容器 |
| Token 定义 | src/AtomUI.Desktop.Controls/Message/MessageToken.cs |
组件级 Design Token |
| 消息卡片主题 | src/AtomUI.Desktop.Controls/Message/Themes/MessageCardTheme.axaml |
MessageCard ControlTheme |
| 容器主题 | src/AtomUI.Desktop.Controls/Message/Themes/WindowMessageManagerTheme.axaml |
WindowMessageManager ControlTheme |
| 主题注册 | src/AtomUI.Desktop.Controls/Message/Themes/MessageThemes.axaml |
主题合并注册 |
| 模板常量 | src/AtomUI.Desktop.Controls/Message/Themes/MessageThemeConstants.cs |
模板部件名称常量 |
| Gallery 示例 | controlgallery/AtomUIGallery/ShowCases/Views/Feedback/MessageShowCase.axaml |
使用范例 |
模板结构
MessageCard 模板
MessageCard 使用 MotionActor 包裹以支持入场/出场动画:
MotionActor (PART_MotionActor) ← 动画容器
└── Border (PART_Frame) ← 主框架(背景、圆角、阴影)
└── DockPanel (PART_HeaderContainer) ← 内容布局容器
├── IconPresenter (PART_IconContent) ← 消息图标(DockPanel.Dock="Left")
└── SelectableTextBlock (PART_Message) ← 消息文本(可选中复制)
设计理由:
- MotionActor 包裹:使整个消息卡片可以参与 Move 动画,实现滑入/滑出效果
- SelectableTextBlock:使用可选择文本控件,用户可以选中并复制消息内容
- DockPanel 布局:图标靠左固定,文本填满剩余空间
WindowMessageManager 模板
ReversibleStackPanel (PART_Items) ← 消息堆叠容器
├── MessageCard ← 消息卡片 1
├── MessageCard ← 消息卡片 2
└── ...
ReversibleStackPanel 支持 ReverseOrder,当 Position 为 TopCenter 时反转堆叠顺序,使最新消息出现在最上方。
模板部件常量
| 常量名 | 值 | 所属 | 说明 |
|---|---|---|---|
MessageCardThemeConstants.FramePart |
"PART_Frame" |
MessageCard | 主框架边框 |
MessageCardThemeConstants.IconContentPart |
"PART_IconContent" |
MessageCard | 图标展示器 |
MessageCardThemeConstants.HeaderContainerPart |
"PART_HeaderContainer" |
MessageCard | 内容布局容器 |
MessageCardThemeConstants.MessagePart |
"PART_Message" |
MessageCard | 消息文本 |
WindowMessageManagerThemeConstants.ItemsPart |
"PART_Items" |
WindowMessageManager | 消息列表面板 |