向treeview添加不同类型的子视图

本文关键字:视图 同类型 treeview 添加 | 更新日期: 2023-09-27 18:13:51

我想在TreeView中可视化Test类(来自模型组装的POCO)的集合。每个Test实例都有ReadersGroups的集合:

测试类伪代码

public class Test 
{
    // properties
   public  ObservableCollection<Reader> Readers { get; set; }
   public  ObservableCollection<Group> Groups { get; set; }
}

我想要的

我的目标是将TreeView中的测试可视化:

Test 1  
   |- Reader 1  
   |- Reader 2  
   |- Group 1   
   |- Group 2
Test 2  
   |- Reader 1  
   |- Group 4   
   |- Group 5

我得到了什么

我可以使用HierarchicalDataTemplate

显示测试和阅读器
<HierarchicalDataTemplate DataType="{x:Type model:Test}" ItemsSource="{Binding Readers}">
    <TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate> 

基本上我想告诉TreeView,"嘿,在我的测试类中有另一个模板的另一个子项目源,使用它!"。

我尝试使用CompositeCollection的读者和组,但卡住了,因为我不想改变测试类(它是生成的代码)。

向treeview添加不同类型的子视图

创建Converter并将其用于HierarchicalDataTemplate.ItemsSource

转换器:

public class ReadersGroupsCombineConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        ObservableCollection<Reader> readers = (value as Test).Readers;
        ObservableCollection<Group> groups = (value as Test).Groups;
        ObservableCollection<object> readersGroups = new ObservableCollection<object>();
        foreach (Reader reader in readers)
            readersGroups.Add(reader);
        foreach (Group group in groups)
            readersGroups.Add(group);
        return readersGroups;
    }
    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

XAML:

    <HierarchicalDataTemplate x:Key="HDTReaderGroups" ItemsSource="{Binding ., Converter={StaticResource ReaderGroupsCombineCnvKey}}">
        <HierarchicalDataTemplate.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}"/>
            </DataTemplate>
        </HierarchicalDataTemplate.ItemTemplate>
        <TextBlock Text="{Binding Name}"/>
    </HierarchicalDataTemplate>

我过去所做的,并建议您这样做,是为您想要在树视图中表示的每种类型创建一个包装器对象。您可以在视图模型中初始化该结构。当你设置好所有的对象后,你可以这样做:

<HierarchicalDataTemplate ItemsSource="{Binding Children}" DataType="{x:Type Model:TestNode}">
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>

现在是子元素的模板:

<HierarchicalDataTemplate ItemsSource="{Binding Children}" DataType="{x:Type Model:ReaderNode}">
    <TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Children}" DataType="{x:Type Model:GroupNode}">
    <TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>

这样,你将有一个模板的每一个类型的对象,你正在建模。

正如我之前所说的,我建议您这样做,因为绑定到不实现INotifyPropertyChanged的对象会泄漏内存,并且poco和dto通常不会实现它。你可以在这里看到更多:https://support.microsoft.com/en-us/kb/938416