如何在WPF层级TreeView中绑定不同类型的选中项?
实现TreeView多类型选中项绑定的几种方案
当然可以实现将TreeView的选中项同时关联到ViewModel中三个不同类型的属性,以下是几种实用方案:
方案一:使用统一Object类型属性联动更新
在ViewModel中新增一个object类型的选中属性,通过它的变更逻辑同步更新三个具体类型的属性:
ViewModel代码
private object _selectedTreeItem; public object SelectedTreeItem { get => _selectedTreeItem; set { _selectedTreeItem = value; // 根据选中项类型赋值对应属性,非对应类型自动为null SelectedProduction = value as Production; SelectedPlant = value as Plant; SelectedScheme = value as Scheme; // 触发所有相关属性的变更通知 OnPropertyChanged(nameof(SelectedTreeItem)); OnPropertyChanged(nameof(SelectedProduction)); OnPropertyChanged(nameof(SelectedPlant)); OnPropertyChanged(nameof(SelectedScheme)); } } // 你原有的三个选中属性 public Production SelectedProduction { get; set; } public Plant SelectedPlant { get; set; } public Scheme SelectedScheme { get; set; } // 假设你的ViewModel实现了INotifyPropertyChanged接口,OnPropertyChanged方法用于通知属性变更
XAML修改
将TreeView的SelectedItem绑定到这个统一属性:
<TreeView ItemsSource="{Binding Menu.productions}" SelectedItem="{Binding SelectedTreeItem}"> <!-- 原有HierarchicalDataTemplate代码保持不变 --> </TreeView>
方案二:使用MultiBinding+自定义转换器
如果不想新增统一属性,可以通过MultiBinding配合转换器,直接将选中项映射到三个具体属性:
自定义转换器代码
public class TreeItemToMultiPropertyConverter : IMultiValueConverter { // 从ViewModel到TreeView的转换无需处理,返回Binding.DoNothing public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { return Binding.DoNothing; } // 将TreeView选中项转换为对应类型的值,分别赋值给三个属性 public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { return new object[] { value as Production, value as Plant, value as Scheme }; } }
XAML配置
先在资源中声明转换器,再设置TreeView的SelectedItem为MultiBinding:
<Window.Resources> <local:TreeItemToMultiPropertyConverter x:Key="TreeItemConverter"/> </Window.Resources> <TreeView ItemsSource="{Binding Menu.productions}"> <TreeView.SelectedItem> <MultiBinding Converter="{StaticResource TreeItemConverter}"> <Binding Path="SelectedProduction" Mode="OneWayToSource"/> <Binding Path="SelectedPlant" Mode="OneWayToSource"/> <Binding Path="SelectedScheme" Mode="OneWayToSource"/> </MultiBinding> </TreeView.SelectedItem> <!-- 原有HierarchicalDataTemplate代码保持不变 --> </TreeView>
方案三:通过统一接口规范节点类型
给三个节点类定义共同接口,ViewModel中使用接口类型的选中属性,既规范又便于扩展:
定义统一接口
public interface ITreeNode { string Name { get; set; } string Id { get; set; } }
修改节点类实现接口
public class Production : ITreeNode { public string Name { get; set; } public string Id { get; set; } public List<Plant> Plants { get; set; } } public class Plant : ITreeNode { public string Name { get; set; } public string Id { get; set; } public List<Scheme> Schemes { get; set; } } public class Scheme : ITreeNode { public string Name { get; set; } public string Id { get; set; } }
ViewModel代码
private ITreeNode _selectedTreeNode; public ITreeNode SelectedTreeNode { get => _selectedTreeNode; set { _selectedTreeNode = value; // 同步更新三个具体属性 SelectedProduction = value as Production; SelectedPlant = value as Plant; SelectedScheme = value as Scheme; OnPropertyChanged(nameof(SelectedTreeNode)); OnPropertyChanged(nameof(SelectedProduction)); OnPropertyChanged(nameof(SelectedPlant)); OnPropertyChanged(nameof(SelectedScheme)); } } // 原有的三个选中属性保留
XAML修改
绑定TreeView的SelectedItem到接口类型属性:
<TreeView ItemsSource="{Binding Menu.productions}" SelectedItem="{Binding SelectedTreeNode}"> <!-- 原有HierarchicalDataTemplate代码保持不变 --> </TreeView>
内容的提问来源于stack exchange,提问作者Alexey Savelyev
相关产品推荐
相关产品推荐

