简单的嵌套 TreeView Xaml 结构?

Simple Nested TreeView Xaml structure?

我正在尝试构建具有三层的 WPF TreeViewCountryReportTitle 是一个字符串 属性 并且 ArticleCategoryTitlesList 是一个集合,它们都来自我的 ViewModel。没有定义 class 层次结构。这是我正在寻找的结构:

这是我的尝试 Xaml 但我在运行时 Xaml 中遇到异常:

{"Item has already been added. Key in dictionary: 'DataTemplateKey(ISESApp.ViewModels.ReportViewModel)'  Key being added: 'DataTemplateKey(ISESApp.ViewModels.ReportViewModel)'"}

Xaml:

       <TreeView ItemsSource="{Binding CountryReportTitle}">
                    <TreeView ItemsSource="{Binding CountryReportTitle}">
                        <TreeView.Resources>
                            <HierarchicalDataTemplate  DataType="{x:Type local:ReportViewModel}"
                                ItemsSource="{Binding ArticleCategoryTitlesList}">
                                <TextBlock Text="{Binding CategoryTitle}" />
                            </HierarchicalDataTemplate>
                            <HierarchicalDataTemplate  DataType="{x:Type local:ReportViewModel}"
                                ItemsSource="{Binding ArticleCatagoryTypesList}">
                                <TextBlock Text="{Binding ArticleTitle}" />
                            </HierarchicalDataTemplate>
                            <DataTemplate  DataType="{x:Type local:ReportViewModel}">
                                <TextBlock Text="{Binding ArticleTitle}" />
                            </DataTemplate>
                        </TreeView.Resources>
                    </TreeView>
                </TreeView>

本地:是我的 ViewModel 的命名空间:

xmlns:local="clr-namespace:MyApp.ViewModels"

我哪里做错了,解决这个问题的最佳方法是什么?

您需要在 TreeView 中绑定 TreeView 资源:

<TreeView.Resources>
    <HierarchicalDataTemplate
        DataType="{x:Type local:FirstLayer}"
        ItemsSource="{Binding Children}">
        <StackPanel Orientation="Horizontal" Margin="2">
            <TextBlock Text="{Binding ChildrenName}" />
        </StackPanel>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate
        DataType="{x:Type local:SecondLayer}"
        ItemsSource="{Binding Children}">
        <StackPanel Orientation="Horizontal" Margin="2">
            <TextBlock Text="{Binding ChildrenName}" />
        </StackPanel>
    </HierarchicalDataTemplate>
</TreeView.Resources>

我认为您需要修改项目以将 Treeview 与 ViewModel 而不是字符串列表绑定

这里有个好东西Example

这是我的树视图示例。

对树中的元素使用 HierarchicalDataTemplate。请注意,一共有三层,每一层都是它自己的类型。这是为了方便,但您可以定义一种类型并为您的树使用一个模板或任何类型的混合。不同的类型在树中代表不同的东西使得使用模板非常方便。

数据类

public class ViewModel
{
    public ObservableCollection<ItemA> ItemsA { get; set; }
    public ViewModel()
    {
        ItemsA = new ObservableCollection<ItemA>(new[]{
            new ItemA{Name = "A one"},
            new ItemA{Name = "A Two"},
            new ItemA{Name = "A Three"},
        });
    }
}

public class ItemA
{
    public ObservableCollection<ItemB> ItemsB { get; set; }
    public string Name { get; set; }
    public ItemA()
    {
        ItemsB = new ObservableCollection<ItemB>(new[]{
            new ItemB{Name = "B one"},
            new ItemB{Name = "B Two"},
            new ItemB{Name = "B Three"},
        });
    }
}
public class ItemB
{
    public ObservableCollection<ItemC> ItemsC { get; set; }
    public string Name { get; set; }
    public ItemB()
    {
        ItemsC = new ObservableCollection<ItemC>(new[]{
            new ItemC{Name = "C one"},
            new ItemC{Name = "C Two"},
            new ItemC{Name = "C Three"},
        });
    }
}
public class ItemC
{
    public string Name { get; set; }
}

还有 UI

 <TreeView ItemsSource="{Binding ItemsA}">
    <TreeView.Resources>
        <HierarchicalDataTemplate  DataType="{x:Type t:ItemA}"
                                    ItemsSource="{Binding ItemsB}">
            <TextBlock Text="{Binding Name}" />
        </HierarchicalDataTemplate>
        <HierarchicalDataTemplate  DataType="{x:Type t:ItemB}"
                                    ItemsSource="{Binding ItemsC}">
            <TextBlock Text="{Binding Name}" />
        </HierarchicalDataTemplate>
        <DataTemplate  DataType="{x:Type t:ItemC}">
            <TextBlock Text="{Binding Name}" />
        </DataTemplate>
    </TreeView.Resources>
</TreeView>

给你一个简单的树视图