# Menu 使用文档 本文档介绍 AtomUI Menu 控件家族的使用方式,涵盖 `Menu`(顶部菜单栏)、`MenuItem`(菜单项)、`ContextMenu`(右键菜单)、`MenuSeparator`(分隔线)和 `MenuFlyout`(弹出菜单)。 > 📖 Gallery 源码位置:`controlgallery/AtomUIGallery/ShowCases/Views/Navigation/MenuShowCase.axaml` --- ## 前置准备 ### AXAML 命名空间 ```xml xmlns:atom="https://atomui.net" xmlns:antdicons="https://atomui.net/icons/antdesign" ``` ### C# 引用 ```csharp using AtomUI.Desktop.Controls; ``` --- ## 1. 基本用法 最简单的菜单栏,包含顶层菜单项和嵌套子菜单。 > 📖 对应 Gallery:`MenuShowCase.axaml` → **"Basic"** ShowCaseItem ```xml ``` **要点:** - `Header` 中的 `_` 前缀字符用于定义键盘访问键(Access Key) - `InputGesture` 用于设置快捷键提示文本 - `MenuSeparator` 用于在菜单项之间插入分隔线 - `IsEnabled="False"` 设置禁用状态 --- ## 2. 通过 ItemsSource 数据驱动生成菜单 使用数据模型和 `ItemTemplate` 动态生成菜单结构,适用于从后端数据或配置动态构建菜单。 > 📖 对应 Gallery:`MenuShowCase.axaml` → **"Generate MenuItem by ItemsSource"** ShowCaseItem ### AXAML ```xml ``` ### ViewModel 数据构建 ```csharp using AtomUI.Desktop.Controls; // 构建菜单数据 var menuItems = new List { new MenuItemData { Header = "File", Children = new List { new MenuItemData { Header = "New Text File" }, new MenuItemData { Header = "New File" }, new MenuSeparatorData(), // 分隔线 new MenuItemData { Header = "Save" }, } }, new MenuItemData { Header = "Edit", Children = new List { new MenuItemData { Header = "Undo" }, new MenuItemData { Header = "Cut", IsEnabled = false }, } } }; // 绑定到 Menu BasicItemsSourceMenu.ItemsSource = menuItems; ``` **要点:** - 使用 `TreeDataTemplate` 以支持嵌套子菜单 - `IMenuItemData.Children` 用于定义子菜单树形结构 - 使用 `MenuSeparatorData` 类型的数据项自动生成 `MenuSeparator` - `MenuItemData` 自动维护 `ParentNode` 父节点引用 --- ## 3. 带图标和子菜单 菜单项可以包含 Ant Design 图标。 > 📖 对应 Gallery:`MenuShowCase.axaml` → **"Icon and submenu"** ShowCaseItem ```xml ``` **要点:** - 使用 `antdicons:AntDesignIconProvider` 标记扩展设置 Ant Design 图标 - 支持多级嵌套子菜单(如 Paste → Paste/Paste from History) - 图标与文字间距由 `MenuToken.ItemIconMarginInlineEnd` Token 控制 --- ## 4. CheckBox / Radio 切换菜单项 菜单项支持 CheckBox 和 Radio 切换交互。 > 📖 对应 Gallery:`MenuShowCase.axaml` → **"menu item with ToggleType"** ShowCaseItem ```xml ``` **要点:** - `ToggleType="Radio"` + `GroupName` 实现同组互斥选择 - `ToggleType="CheckBox"` 实现独立选中/取消 - 可同时设置图标和 ToggleType - 通过 `IsCheckStateChanged` 事件监听选中状态变化 ### 监听选中变化 ```csharp menuItem.IsCheckStateChanged += (sender, e) => { var item = (MenuItem)sender!; Console.WriteLine($"{item.Header}: IsChecked = {item.IsChecked}"); }; ``` --- ## 5. 可滚动菜单 当子菜单项过多时,弹窗会自动出现滚动条。`DisplayPageSize` 控制可见项数量。 > 📖 对应 Gallery:`MenuShowCase.axaml` → **"Scrollable menu"** ShowCaseItem ```xml ``` **要点:** - 默认 `DisplayPageSize=10`,即弹窗最多显示 10 项,超出后出现滚动条 - 可以通过设置 `DisplayPageSize` 调整可见项数量 --- ## 6. 右键上下文菜单(ContextMenu) 通过 `ContextMenu` 属性附加到任意控件,右键点击触发弹出。 > 📖 对应 Gallery:`MenuShowCase.axaml` → **"Context menu"** ShowCaseItem ```xml ``` ### 数据驱动的 ContextMenu > 📖 对应 Gallery:`MenuShowCase.axaml` → **"Context menu, Generate MenuItem by ItemsSource"** ShowCaseItem ```xml ``` --- ## 7. MenuFlyout 弹出菜单 `MenuFlyout` 可作为 `ContextFlyout` 使用,通过右键触发弹出。 > 📖 对应 Gallery:`MenuShowCase.axaml` → **"Menu Flyout"** ShowCaseItem ```xml ``` ### 数据驱动的 MenuFlyout ```xml ``` --- ## 8. 尺寸变体 Menu 支持三种尺寸:`Small`、`Middle`(默认)、`Large`。尺寸影响菜单栏的最小高度、顶层菜单项的内间距和字体大小。 ```xml ``` **尺寸影响的 Token 对应关系:** | SizeType | 最小高度 | 顶层圆角 | 顶层内间距 | 顶层字体 | |---|---|---|---|---| | `Large` | `ControlHeightLG` | `TopLevelItemBorderRadiusLG` | `TopLevelItemPaddingLG` | `TopLevelItemFontSizeLG` | | `Middle` | `ControlHeight` | `TopLevelItemBorderRadius` | `TopLevelItemPadding` | `TopLevelItemFontSize` | | `Small` | `ControlHeightSM` | `TopLevelItemBorderRadiusSM` | `TopLevelItemPaddingSM` | `TopLevelItemFontSizeSM` | --- ## 9. 动画控制 通过 `IsMotionEnabled` 属性控制子菜单弹出/关闭的动画效果。默认跟随全局 Token `EnableMotion`。 ```xml ``` --- ## 常见场景 ### 应用顶部菜单栏 ```xml ``` ### 右键上下文菜单 + Command 绑定 ```xml ```