直接用
ItemsSource+
TreeDataTemplate就能实现层级绑定,关键是数据模型要支持递归嵌套,且集合类型得是可观察的(比如
ObservableCollection<t></t>)。
数据模型必须带子节点集合
每个节点类需包含一个表示子项的可观察集合属性,通常叫
Children或
SubNodes。Avalonia 会自动识别该属性并递归渲染: 必须实现
INotifyPropertyChanged(用于响应属性变更)
Children类型必须是
ObservableCollection<t></t>,不能是
List<t></t>或普通数组 子节点对象本身也得符合同样结构,才能继续展开
示例节点类:
public class Node : INotifyPropertyChanged
{
private string _title;
public string Title
{
get => _title;
set { _title = value; OnPropertyChanged(); }
}
public ObservableCollection<Node> SubNodes { get; } = new();
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string? name = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
XAML 中用 TreeDataTemplate 声明递归结构
不是用普通
DataTemplate,而是
TreeDataTemplate,并指定其
ItemsSource绑定到子集合属性:
TreeView.ItemTemplate必须是
TreeDataTemplate
ItemsSource属性写在
TreeDataTemplate标签内,值为
{Binding SubNodes}
模板内部可自由定义节点外观,比如 TextBlock显示标题
典型写法:
<TreeView ItemsSource="{Binding RootNodes}">
<TreeView.ItemTemplate>
<TreeDataTemplate ItemsSource="{Binding SubNodes}">
<TextBlock Text="{Binding Title}" />
</TreeDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
ViewModel 提供根节点集合
TreeView的
ItemsSource绑定的是顶层节点集合,它本身也得是可观察的: 在 ViewModel 中声明
ObservableCollection<node> RootNodes { get; }</node>
初始化时填入一级节点,每个节点再自行填充 SubNodes支持动态增删:往某节点的
SubNodes添加新
Node,UI 自动更新
例如:
RootNodes = new ObservableCollection<Node>
{
new Node { Title = "文档" }
{
SubNodes = { new Node { Title = "README.md" }, new Node { Title = "LICENSE" } }
},
new Node { Title = "源码" }
{
SubNodes = { new Node { Title = "Program.cs" } }
}
};
展开/折叠和选中状态不用手动处理
Avalonia 默认已支持:
点击箭头图标自动展开/收起子节点 支持单选(SelectionMode="Single")或多选(
SelectionMode="Multiple") 选中状态变化会触发
SelectedItem或
SelectedItems绑定 如需自定义样式,可用
Style针对
TreeViewItem的
:selected状态设置前景色、背景等
基本上就这些。只要模型对、模板对、集合可观察,层级就自然出来了。不复杂但容易忽略
ObservableCollection和
INotifyPropertyChanged这两个关键点。
