# TreeSelect 使用文档 本文档介绍 AtomUI TreeSelect 控件的各种使用方式,示例代码摘自 Gallery 演示程序。 > 📖 Gallery 源码位置:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/TreeSelectShowCase.axaml` --- ## 前置准备 在 AXAML 中使用 TreeSelect,需要引入以下命名空间: ```xml xmlns:atom="https://atomui.net" xmlns:antdicons="https://atomui.net/icons/antdesign" ``` 在 C# 代码中引入: ```csharp using AtomUI.Desktop.Controls; // TreeSelect 控件 using AtomUI.Controls; // SizeType, ITreeItemNode, TreeItemNode 等共享类型 ``` --- ## 1. 基本用法(单选) 最基本的 TreeSelect 使用方式——单选模式,点击节点即选中,弹窗自动关闭。 ```xml ``` ```csharp // Code-behind:构建树形数据源 var treeNodes = new List { new TreeItemNode() { Header = "parent 1", Value = "parent 1", Children = [ new TreeItemNode() { Header = "parent 1-0", Value = "parent 1-0", Children = [ new TreeItemNode() { Header = "leaf1", Value = "leaf1" }, new TreeItemNode() { Header = "leaf2", Value = "leaf2" }, ] }, new TreeItemNode() { Header = "parent 1-1", Value = "parent 1-1", Children = [ new TreeItemNode() { Header = "leaf11", Value = "leaf11" } ] } ] } }; BasicTreeSelect.ItemsSource = treeNodes; ``` **要点**: - `IsDefaultExpandAll="True"` 使所有节点默认展开 - `IsAllowClear="True"` 在选中后显示清除按钮 - `IsFilterEnabled="True"` 启用搜索筛选功能 --- ## 2. 多选模式 设置 `IsMultiple="True"` 启用多选模式,选中项以 Tag 形式展示在输入框中。 ```xml ``` ```csharp vm.MultiSelectionTreeNodes = new List { new TreeItemNode() { Header = "parent 1", Value = "parent 1", Children = [ new TreeItemNode() { Header = "parent 1-0", Value = "parent 1-0", Children = [ new TreeItemNode() { Header = "my leaf", Value = "leaf1" }, new TreeItemNode() { Header = "your leaf", Value = "leaf2" } ] }, new TreeItemNode() { Header = "parent 1-1", Value = "parent 1-1", Children = [ new TreeItemNode() { Header = "sss", Value = "sss" } ] } ] }, }; ``` --- ## 3. 通过 ItemsSource 绑定数据 使用 `ItemsSource` 属性绑定树形数据源是推荐的 MVVM 数据驱动方式: ```xml ``` ```csharp // 使用 ReactiveUI 绑定 this.OneWayBind(ViewModel, vm => vm.TreeNodes, v => v.ItemsSourceTreeSelect.ItemsSource) .DisposeWith(disposables); ``` ```csharp // ViewModel vm.TreeNodes = new List { new TreeItemNode() { Header = "Node1", Value = "0-0", Children = [ new TreeItemNode() { Header = "Child Node1", Value = "0-0-1" }, new TreeItemNode() { Header = "Child Node2", Value = "0-0-2" } ] }, new TreeItemNode() { Header = "Node2", Value = "0-1", } }; ``` --- ## 4. 勾选模式(Checkable) 设置 `IsTreeCheckable="True"` 启用 Checkbox 勾选模式,支持父子联动。配合 `ShowCheckedStrategy` 控制展示策略。 ```xml ``` ```csharp vm.CheckableTreeNodes = new List { new TreeItemNode() { Header = "Node1", ItemKey = "0-0", Children = [ new TreeItemNode() { Header = "Child Node1", Value = "0-0-0" } ] }, new TreeItemNode() { Header = "Node2", ItemKey = "0-1", Children = [ new TreeItemNode() { Header = "Child Node3", Value = "0-1-0" }, new TreeItemNode() { Header = "Child Node4", Value = "0-1-1", Children = [ new TreeItemNode() { Header = "Child Node6", Value = "0-1-1-0" }, new TreeItemNode() { Header = "Child Node7", Value = "0-1-1-1" }, ] }, new TreeItemNode() { Header = "Child Node5", Value = "0-1-2" } ] } }; ``` **勾选策略说明**: - `ShowCheckedStrategy="All"`:展示所有勾选节点 - `ShowCheckedStrategy="ShowParent"`:当所有子节点都勾选时仅展示父节点 - `ShowCheckedStrategy="ShowChild"`:仅展示叶子节点 --- ## 5. 异步加载 通过 `DataLoader` 属性提供异步加载器,实现展开节点时按需加载子节点: ```xml ``` ```csharp // 初始化根节点 vm.AsyncLoadTreeNodes = new List { new TreeItemNode() { Header = "Expand to load", ItemKey = "0" }, new TreeItemNode() { Header = "Expand to load", ItemKey = "1" }, new TreeItemNode() { Header = "Tree Node", ItemKey = "2", IsLeaf = true } }; // 绑定异步加载器 vm.AsyncLoadTreeNodeLoader = new TreeItemDataLoader(); this.OneWayBind(ViewModel, vm => vm.AsyncLoadTreeNodeLoader, v => v.AsyncLoadTreeSelect.DataLoader) .DisposeWith(disposables); ``` ```csharp // 自定义加载器实现 ITreeItemNodeLoader 接口 public class TreeItemDataLoader : ITreeItemNodeLoader { public async Task> LoadChildrenAsync(ITreeItemNode parentNode, CancellationToken cancellationToken) { await Task.Delay(1000, cancellationToken); // 模拟异步加载 return new List { new TreeItemNode() { Header = $"Child of {parentNode.Header}", Value = "child-1" }, new TreeItemNode() { Header = $"Another child", Value = "child-2", IsLeaf = true } }; } } ``` **要点**:非叶子节点展开时自动调用 `DataLoader`,加载过程中显示旋转图标。设置 `IsLeaf = true` 的节点不会触发加载。 --- ## 6. 弹窗位置 通过 `Placement` 属性和 `IsPopupMatchSelectWidth` 属性控制弹窗弹出位置: ```xml ``` ```csharp // ViewModel 中动态切换弹窗位置 public void HandlePlacementOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) { if (args.Index == 0) vm.Placement = SelectPopupPlacement.TopEdgeAlignedLeft; else if (args.Index == 1) vm.Placement = SelectPopupPlacement.TopEdgeAlignedRight; else if (args.Index == 2) vm.Placement = SelectPopupPlacement.BottomEdgeAlignedLeft; else vm.Placement = SelectPopupPlacement.BottomEdgeAlignedRight; } ``` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/TreeSelectShowCase.axaml` 中 "Placement" 示例。 --- ## 7. 显示树线 通过 `IsShowLine`、`IsShowIcon`、`IsShowLeafIcon`、`IsSwitcherRotation` 属性控制树形结构的视觉展示: ```xml ``` ```csharp // 数据中可以为节点指定图标 vm.ShowTreeLineTreeNodes = new List { new TreeItemNode() { Header = "parent 1", ItemKey = "parent 1", Children = [ new TreeItemNode() { Header = "parent 1-0", Value = "parent 1-0", Icon = new CarryOutOutlined(), Children = [ new TreeItemNode() { Header = "Leaf1", ItemKey = "Leaf1", IsLeaf = true, Icon = new CarryOutOutlined(), } ] } ] } }; ``` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/TreeSelectShowCase.axaml` 中 "Show Tree Line" 示例。 --- ## 8. 样式变体 TreeSelect 支持四种样式变体,通过 `StyleVariant` 属性设置: ```xml ``` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/TreeSelectShowCase.axaml` 中 "Variants" 示例。 --- ## 9. 验证状态 通过 `Status` 属性设置 Error 或 Warning 状态,配合表单验证使用: ```xml ``` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/TreeSelectShowCase.axaml` 中 "Status" 示例。 --- ## 10. 前缀附加内容 通过 `LeftAddOn` 和 `ContentLeftAddOn` 属性为 TreeSelect 添加前缀内容: ```xml ``` > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/TreeSelectShowCase.axaml` 中 "Prefix and Suffix" 示例。 --- ## 11. 最大选择数量 在多选/勾选模式下,通过 `MaxCount` 限制最大可选数量。达到上限后未选中节点自动禁用: ```xml ``` **要点**: - `IsShowMaxCountIndicator="True"` 在右侧显示 `已选/最大` 数量指示器 - 当选中数量达到 `MaxCount` 时,`TreeSelectTreeViewItem` 会通过 `IsMaxSelectReached` 属性将未选中/未勾选的节点禁用 > 📖 参考:`controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/TreeSelectShowCase.axaml` 中 "Max Count" 示例。 --- ## 12. 获取选中值 ### 单选模式 ```csharp // 通过 SelectedItem 获取选中的节点 ITreeItemNode? selected = myTreeSelect.SelectedItem; if (selected != null) { Console.WriteLine($"Selected: {selected.Header} (Value: {selected.Value})"); } ``` ### 多选/勾选模式 ```csharp // 通过 SelectedItems 获取所有选中的节点 IList? selectedItems = myTreeSelect.SelectedItems; if (selectedItems != null) { foreach (var item in selectedItems) { Console.WriteLine($"Selected: {item.Header}"); } } ``` ### 清空选中项 ```csharp // 调用 Clear() 方法清空所有选中项 myTreeSelect.Clear(); ``` --- ## 常见组合模式 ### 表单中使用 TreeSelect ```xml ``` ### 多选 + 搜索 + 最大数量限制 ```xml ``` ### 勾选 + 仅展示叶子节点 ```xml ``` ### 异步加载 + 搜索 ```xml ```