16 KiB
TreeSelect 使用文档
本文档介绍 AtomUI TreeSelect 控件的各种使用方式,示例代码摘自 Gallery 演示程序。
📖 Gallery 源码位置:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/TreeSelectShowCase.axaml
前置准备
在 AXAML 中使用 TreeSelect,需要引入以下命名空间:
xmlns:atom="https://atomui.net"
xmlns:antdicons="https://atomui.net/icons/antdesign"
在 C# 代码中引入:
using AtomUI.Desktop.Controls; // TreeSelect 控件
using AtomUI.Controls; // SizeType, ITreeItemNode, TreeItemNode 等共享类型
1. 基本用法(单选)
最基本的 TreeSelect 使用方式——单选模式,点击节点即选中,弹窗自动关闭。
<atom:TreeSelect Name="BasicTreeSelect"
HorizontalAlignment="Stretch"
IsDefaultExpandAll="True"
IsAllowClear="True"
IsFilterEnabled="True"
PlaceholderText="Please select" />
// Code-behind:构建树形数据源
var treeNodes = new List<TreeItemNode>
{
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 形式展示在输入框中。
<atom:TreeSelect Name="MultiSelectionTreeSelect"
HorizontalAlignment="Stretch"
IsDefaultExpandAll="True"
IsAllowClear="True"
IsFilterEnabled="True"
IsMultiple="True"
PlaceholderText="Please select" />
vm.MultiSelectionTreeNodes = new List<TreeItemNode>
{
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 数据驱动方式:
<atom:TreeSelect Name="ItemsSourceTreeSelect"
HorizontalAlignment="Stretch"
IsDefaultExpandAll="True"
IsAllowClear="True"
IsFilterEnabled="True"
PlaceholderText="Please select" />
// 使用 ReactiveUI 绑定
this.OneWayBind(ViewModel, vm => vm.TreeNodes, v => v.ItemsSourceTreeSelect.ItemsSource)
.DisposeWith(disposables);
// ViewModel
vm.TreeNodes = new List<TreeItemNode>
{
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 控制展示策略。
<atom:TreeSelect Name="CheckableTreeSelect"
HorizontalAlignment="Stretch"
IsDefaultExpandAll="True"
IsAllowClear="True"
IsFilterEnabled="True"
IsTreeCheckable="True"
PlaceholderText="Please select"
ShowCheckedStrategy="ShowParent" />
vm.CheckableTreeNodes = new List<TreeItemNode>
{
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 属性提供异步加载器,实现展开节点时按需加载子节点:
<atom:TreeSelect Name="AsyncLoadTreeSelect"
HorizontalAlignment="Stretch"
IsAllowClear="True"
PlaceholderText="Please select" />
// 初始化根节点
vm.AsyncLoadTreeNodes = new List<TreeItemNode>
{
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);
// 自定义加载器实现 ITreeItemNodeLoader 接口
public class TreeItemDataLoader : ITreeItemNodeLoader
{
public async Task<IList<ITreeItemNode>> LoadChildrenAsync(ITreeItemNode parentNode, CancellationToken cancellationToken)
{
await Task.Delay(1000, cancellationToken); // 模拟异步加载
return new List<ITreeItemNode>
{
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 属性控制弹窗弹出位置:
<atom:TreeSelect Name="PlacementTreeSelect"
IsAllowClear="True"
PlaceholderText="Please select"
IsDefaultExpandAll="True"
IsFilterEnabled="True"
IsPopupMatchSelectWidth="False"
Placement="{Binding Placement}" />
// 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 属性控制树形结构的视觉展示:
<atom:ToggleSwitch OnContent="ShowIcon" OffContent="ShowIcon" Name="ShowIconSwitch" />
<atom:ToggleSwitch OnContent="TreeLine" OffContent="TreeLine" IsChecked="True"
Name="ShowTreeLineSwitch" />
<atom:ToggleSwitch OnContent="ShowLeafIcon" OffContent="ShowLeafIcon" Name="ShowLeafIconSwitch" />
<atom:TreeSelect Name="ShowTreeLineTreeSelect"
HorizontalAlignment="Stretch"
IsAllowClear="True"
PlaceholderText="Please select"
IsShowIcon="{Binding #ShowIconSwitch.IsChecked}"
IsShowLeafIcon="{Binding #ShowLeafIconSwitch.IsChecked}"
IsShowLine="{Binding #ShowTreeLineSwitch.IsChecked}"
IsSwitcherRotation="{Binding #ShowTreeLineSwitch.IsChecked,
Converter={x:Static BoolConverters.Not}}" />
// 数据中可以为节点指定图标
vm.ShowTreeLineTreeNodes = new List<TreeItemNode>
{
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 属性设置:
<StackPanel Orientation="Vertical" Spacing="10">
<atom:TreeSelect HorizontalAlignment="Stretch"
IsAllowClear="True"
PlaceholderText="Outline (default)"
StyleVariant="Outline" />
<atom:TreeSelect HorizontalAlignment="Stretch"
IsAllowClear="True"
PlaceholderText="Filled"
StyleVariant="Filled" />
<atom:TreeSelect HorizontalAlignment="Stretch"
IsAllowClear="True"
PlaceholderText="Borderless"
StyleVariant="Borderless" />
<atom:TreeSelect HorizontalAlignment="Stretch"
IsAllowClear="True"
PlaceholderText="Underlined"
StyleVariant="Underlined" />
</StackPanel>
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/TreeSelectShowCase.axaml中 "Variants" 示例。
9. 验证状态
通过 Status 属性设置 Error 或 Warning 状态,配合表单验证使用:
<StackPanel Orientation="Vertical" Spacing="10">
<atom:TreeSelect HorizontalAlignment="Stretch"
IsAllowClear="True"
PlaceholderText="Error status"
Status="Error" />
<atom:TreeSelect HorizontalAlignment="Stretch"
IsAllowClear="True"
PlaceholderText="Warning status"
Status="Warning" />
</StackPanel>
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/TreeSelectShowCase.axaml中 "Status" 示例。
10. 前缀附加内容
通过 LeftAddOn 和 ContentLeftAddOn 属性为 TreeSelect 添加前缀内容:
<!-- LeftAddOn:独立的左侧装饰区域 -->
<atom:TreeSelect Name="LeftAddTreeSelect"
HorizontalAlignment="Stretch"
IsAllowClear="True"
PlaceholderText="Please select"
IsDefaultExpandAll="True"
LeftAddOn="Prefix"
IsFilterEnabled="True" />
<!-- ContentLeftAddOn:内容区域内的左侧前缀 -->
<atom:TreeSelect Name="ContentLeftAddTreeSelect"
HorizontalAlignment="Stretch"
IsAllowClear="True"
PlaceholderText="Please select"
IsDefaultExpandAll="True"
ContentLeftAddOn="Prefix"
IsFilterEnabled="True" />
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/TreeSelectShowCase.axaml中 "Prefix and Suffix" 示例。
11. 最大选择数量
在多选/勾选模式下,通过 MaxCount 限制最大可选数量。达到上限后未选中节点自动禁用:
<!-- 多选模式 + MaxCount -->
<atom:TreeSelect Name="MaxSelectedTreeSelect"
HorizontalAlignment="Stretch"
IsDefaultExpandAll="True"
IsMultiple="True"
IsAllowClear="True"
IsFilterEnabled="True"
PlaceholderText="Please select"
IsShowMaxCountIndicator="True"
MaxCount="3" />
<!-- 勾选模式 + MaxCount -->
<atom:TreeSelect Name="MaxCheckedTreeSelect"
HorizontalAlignment="Stretch"
IsDefaultExpandAll="True"
IsMultiple="True"
IsTreeCheckable="True"
IsAllowClear="True"
IsFilterEnabled="True"
PlaceholderText="Please select"
IsShowMaxCountIndicator="True"
MaxCount="3" />
要点:
IsShowMaxCountIndicator="True"在右侧显示已选/最大数量指示器- 当选中数量达到
MaxCount时,TreeSelectTreeViewItem会通过IsMaxSelectReached属性将未选中/未勾选的节点禁用
📖 参考:
controlgallery/AtomUIGallery/ShowCases/Views/DataEntry/TreeSelectShowCase.axaml中 "Max Count" 示例。
12. 获取选中值
单选模式
// 通过 SelectedItem 获取选中的节点
ITreeItemNode? selected = myTreeSelect.SelectedItem;
if (selected != null)
{
Console.WriteLine($"Selected: {selected.Header} (Value: {selected.Value})");
}
多选/勾选模式
// 通过 SelectedItems 获取所有选中的节点
IList<ITreeItemNode>? selectedItems = myTreeSelect.SelectedItems;
if (selectedItems != null)
{
foreach (var item in selectedItems)
{
Console.WriteLine($"Selected: {item.Header}");
}
}
清空选中项
// 调用 Clear() 方法清空所有选中项
myTreeSelect.Clear();
常见组合模式
表单中使用 TreeSelect
<atom:FormItem Label="Department">
<atom:TreeSelect IsAllowClear="True"
PlaceholderText="Select department"
HorizontalAlignment="Stretch" />
</atom:FormItem>
多选 + 搜索 + 最大数量限制
<atom:TreeSelect IsMultiple="True"
IsFilterEnabled="True"
IsAllowClear="True"
MaxCount="5"
IsShowMaxCountIndicator="True"
PlaceholderText="Select up to 5 items"
HorizontalAlignment="Stretch" />
勾选 + 仅展示叶子节点
<atom:TreeSelect IsTreeCheckable="True"
ShowCheckedStrategy="ShowChild"
IsAllowClear="True"
IsDefaultExpandAll="True"
PlaceholderText="Select leaf nodes"
HorizontalAlignment="Stretch" />
异步加载 + 搜索
<atom:TreeSelect IsFilterEnabled="True"
IsAllowClear="True"
DataLoader="{Binding MyDataLoader}"
PlaceholderText="Search and load"
HorizontalAlignment="Stretch" />