一、绑定方式
在使用WPF TreeView进行数据绑定的时候,常见的几种方式有以下几种。
1. 使用静态数据源
<TreeView>
<TreeViewItem Header="节点1">
<TreeViewItem Header="节点1子节点1" />
<TreeViewItem Header="节点1子节点2" />
</TreeViewItem>
<TreeViewItem Header="节点2">
<TreeViewItem Header="节点2子节点1" />
<TreeViewItem Header="节点2子节点2" />
</TreeViewItem>
</TreeView>
2. 使用Binding绑定动态数据源
public class TreeNode
{
public string Header { get; set; }
public ObservableCollection<TreeNode> Children { get; set; }
}
public class TreeViewModel
{
public ObservableCollection<TreeNode> RootNodes { get; set; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new TreeViewModel() { RootNodes = /*your observable collection here*/ };
}
}
<Window>
<TreeView ItemsSource="{Binding RootNodes}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Header}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Window>
二、绑定到TreeViewItem
有时候,需要将数据绑定到TreeViewItem本身,并使用该数据去匹配TreeViewItem的模板。可以使用DataTemplate。
<Window.Resources>
<DataTemplate DataType="{x:Type local:TreeNode}">
<TextBlock Text="{Binding Header}" />
</DataTemplate>
</Window.Resources>
<Window>
<TreeView ItemsSource="{Binding RootNodes}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True" />
<Setter Property="Header" Value="{Binding}" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
</Window>
三、绑定到TreeViewItem的Header
另外一种常见的Treeview数据绑定方式,是将数据绑定到TreeViewItem的Header属性,方法同样是使用DataTemplate。这种方式可以在TreeView显示多种风格和数据类型的节点。
<Window>
<Window.Resources>
<DataTemplate DataType="{x:Type local:TreeNode}">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ImageUri}" Width="16" Height="16" />
<TextBlock Margin="5,0,0,0" Text="{Binding Header}" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<TreeView ItemsSource="{Binding RootNodes}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
</TreeView>
</Window>
四、MVVM绑定
在MVVM模式中,ViewModel是数据的源头,View则是呈现数据的界面,二者通过数据绑定实现解耦。使用MVVM模式实现WPF TreeView数据绑定是非常常见的,以下是一个简单的示例。
public class TreeNodeViewModel
{
public string Header { get; set; }
public ObservableCollection<TreeNodeViewModel> Children { get; set; }
}
public class TreeViewViewModel : INotifyPropertyChanged
{
public ObservableCollection<TreeNodeViewModel> RootNodes { get; set; }
private TreeNodeViewModel _selectedNode;
public TreeNodeViewModel SelectedNode
{
get { return _selectedNode; }
set
{
_selectedNode = value;
OnPropertyChanged("SelectedNode");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new TreeViewViewModel() { RootNodes = /*your observable collection here*/ };
}
}
<Window>
<TreeView ItemsSource="{Binding RootNodes}" SelectedItem="{Binding SelectedNode}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Header}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</Window>
五、数据排序
WPF TreeView提供了对节点的默认排序,可以按字母顺序排序、降序排序等。此外,也可以实现自定义排序。
public class TreeNode : IComparable
{
public string Header { get; set; }
public ObservableCollection<TreeNode> Children { get; set; }
public int CompareTo(object obj)
{
TreeNode other = obj as TreeNode;
if (other == null) return 0;
return Header.CompareTo(other.Header);
}
}
<Window>
<TreeView ItemsSource="{Binding RootNodes}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}">
<TextBlock Text="{Binding Header}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="True" />
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Items.SortDescriptions>
<scm:SortDescription PropertyName="Header" Direction="Ascending" />
</TreeView.Items.SortDescriptions>
</TreeView>
</Window>