将不同类型的子项添加到树视图中

时间:2016-10-19 14:11:56

标签: c# wpf treeview

我想在Test中可视化TreeView类(来自模型装配的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读者和群组,但因为我不想更改Test类(它是生成的代码)而陷入困境。

2 个答案:

答案 0 :(得分:1)

创建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>

答案 1 :(得分:0)

我过去做过的,建议你做的是为你想在树视图中表示的每种类型创建一个包装器对象。您可以在viewmodel中初始化该结构。设置完所有对象后,即可执行以下操作:

<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