# Message 使用文档 本文档介绍 AtomUI Message 控件的各种使用方式,示例代码摘自 Gallery 演示程序。 > 📖 Gallery 源码位置:`controlgallery/AtomUIGallery/ShowCases/Views/Feedback/MessageShowCase.axaml` --- ## 前置准备 在 AXAML 中使用 Message,需要引入以下命名空间: ```xml xmlns:atom="https://atomui.net" ``` 在 C# 代码中引入: ```csharp using AtomUI.Desktop.Controls; // Message, MessageCard, WindowMessageManager using Avalonia.Controls; // TopLevel ``` --- ## 1. 初始化 WindowMessageManager Message 系统使用命令式 API(而非 AXAML 声明式),需要先在代码中初始化 `WindowMessageManager`: ```csharp public partial class MyView : UserControl { private WindowMessageManager? _messageManager; protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { base.OnAttachedToVisualTree(e); var topLevel = TopLevel.GetTopLevel(this); _messageManager = new WindowMessageManager(topLevel) { MaxItems = 10 // 最多同时显示 10 条消息 }; } protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) { base.OnDetachedFromVisualTree(e); _messageManager?.Dispose(); // 必须释放资源 _messageManager = null; } } ``` **关键要点**: - `WindowMessageManager` 需要一个 `TopLevel` 实例作为宿主,它会自动挂载到该窗口的 `AdornerLayer` 上 - 在 `OnDetachedFromVisualTree` 中必须调用 `Dispose()` 释放资源,避免内存泄漏 - 一个 `TopLevel` 通常只需要一个 `WindowMessageManager` 实例 > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/Feedback/MessageShowCase.axaml.cs` --- ## 2. 基本用法 最简单的使用方式——显示一条默认类型的消息: ```xml Display normal message ``` ```csharp private void ShowSimpleMessage(object? sender, RoutedEventArgs e) { _messageManager?.Show(new Message("Hello, AtomUI/Avalonia!")); } ``` 默认使用 `MessageType.Information` 类型,显示蓝色 `InfoCircleFilled` 图标,5 秒后自动关闭。 --- ## 3. 不同消息类型 通过 `MessageType` 参数设置不同的消息类型,每种类型有对应的图标和颜色: ```xml Success Info Warning Error ``` ```csharp private void ShowSuccessMessage(object? sender, RoutedEventArgs e) { _messageManager?.Show(new Message( type: MessageType.Success, content: "This is a success message." )); } private void ShowInfoMessage(object? sender, RoutedEventArgs e) { _messageManager?.Show(new Message( type: MessageType.Information, content: "This is a information message." )); } private void ShowWarningMessage(object? sender, RoutedEventArgs e) { _messageManager?.Show(new Message( type: MessageType.Warning, content: "This is a warning message." )); } private void ShowErrorMessage(object? sender, RoutedEventArgs e) { _messageManager?.Show(new Message( type: MessageType.Error, content: "This is a error message." )); } ``` **类型对应关系**: - `Information` → 蓝色 `InfoCircleFilled` 图标 - `Success` → 绿色 `CheckCircleFilled` 图标 - `Warning` → 黄色 `ExclamationCircleFilled` 图标 - `Error` → 红色 `CloseCircleFilled` 图标 --- ## 4. Loading 消息 Loading 类型消息显示旋转的加载图标,适用于异步操作进行中的提示: ```xml Display a loading indicator ``` ```csharp private void ShowLoadingMessage(object? sender, RoutedEventArgs e) { _messageManager?.Show(new Message( type: MessageType.Loading, content: "Action in progress..." )); } ``` Loading 消息的 `LoadingOutlined` 图标会自动播放旋转动画。 --- ## 5. 自定义持续时间 通过 `expiration` 参数控制消息的显示时长: ```csharp // 10 秒后关闭 _messageManager?.Show(new Message( content: "This message will last 10 seconds", expiration: TimeSpan.FromSeconds(10) )); // 永不自动关闭(需要手动关闭) _messageManager?.Show(new Message( content: "This message won't auto-close", expiration: TimeSpan.Zero )); // 快速消失(1 秒) _messageManager?.Show(new Message( content: "Quick flash", type: MessageType.Success, expiration: TimeSpan.FromSeconds(1) )); ``` --- ## 6. 关闭回调(链式消息) 通过 `onClose` 参数在消息关闭后执行回调,可以实现链式消息——一条消息关闭后自动显示下一条: ```xml Display sequential messages ``` ```csharp private void ShowSequentialMessage(object? sender, RoutedEventArgs e) { _messageManager?.Show(new Message( type: MessageType.Loading, content: "Action in progress...", expiration: TimeSpan.FromSeconds(2.5), onClose: () => { _messageManager?.Show(new Message( type: MessageType.Success, expiration: TimeSpan.FromSeconds(2.5), content: "Loading finished", onClose: () => { _messageManager?.Show(new Message( type: MessageType.Information, expiration: TimeSpan.FromSeconds(2.5), content: "Loading finished" )); } )); } )); } ``` 这个示例展示了典型的异步操作流程:**Loading → Success → Info**,通过 `onClose` 回调串联。 --- ## 7. 自定义图标 通过 `icon` 参数使用自定义 Ant Design 图标替代默认图标: ```csharp using AtomUI.Icons.AntDesign; // 使用自定义图标 _messageManager?.Show(new Message( content: "This message has a custom icon", icon: new SmileFilled() )); ``` --- ## 8. 动态更新消息内容 `Message` 实现了 `INotifyPropertyChanged`,可以在消息显示后动态更新内容: ```csharp var message = new Message( content: "Uploading... 0%", type: MessageType.Loading, expiration: TimeSpan.Zero // 不自动关闭 ); _messageManager?.Show(message); // 后续更新内容 Dispatcher.UIThread.InvokeAsync(async () => { for (int i = 1; i <= 100; i++) { await Task.Delay(50); message.Content = $"Uploading... {i}%"; } message.Content = "Upload complete!"; }); ``` --- ## 9. 附加样式类 `Show` 方法的 `classes` 参数允许为单条消息附加自定义样式类: ```csharp // 附加自定义样式类 _messageManager?.Show( new Message("Important notification!", MessageType.Warning), classes: new[] { "important", "bold" } ); ``` 在 AXAML 中定义对应的样式: ```xml ``` --- ## 10. 控制最大显示数量 通过 `MaxItems` 属性限制同时显示的消息数量,超出时最早的消息会被自动关闭: ```csharp _messageManager = new WindowMessageManager(topLevel) { MaxItems = 3 // 最多同时显示 3 条 }; ``` --- ## 常见使用模式 ### 表单提交反馈 ```csharp private async void OnSubmit(object? sender, RoutedEventArgs e) { try { _messageManager?.Show(new Message( content: "Submitting...", type: MessageType.Loading, expiration: TimeSpan.Zero )); await _service.SubmitAsync(); _messageManager?.Show(new Message( content: "Submit successful!", type: MessageType.Success )); } catch (Exception ex) { _messageManager?.Show(new Message( content: $"Submit failed: {ex.Message}", type: MessageType.Error, expiration: TimeSpan.FromSeconds(10) )); } } ``` ### MVVM 模式下的使用 ```csharp // ViewModel 中通过接口引用 public class MyViewModel : ReactiveObject { private readonly IMessageManager _messageManager; public MyViewModel(IMessageManager messageManager) { _messageManager = messageManager; } public void ShowSuccess(string content) { _messageManager.Show(new Message(content, MessageType.Success)); } } ``` ### 与操作确认结合 ```csharp private void OnDelete(object? sender, RoutedEventArgs e) { // 先显示 Loading,操作完成后显示结果 _messageManager?.Show(new Message( content: "Deleting...", type: MessageType.Loading, expiration: TimeSpan.FromSeconds(2), onClose: () => { _messageManager?.Show(new Message( content: "Deleted successfully", type: MessageType.Success )); } )); } ```