Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 简单嵌套TreeView Xaml结构?_C#_Wpf_Xaml_Mvvm_Treeview - Fatal编程技术网

C# 简单嵌套TreeView Xaml结构?

C# 简单嵌套TreeView Xaml结构?,c#,wpf,xaml,mvvm,treeview,C#,Wpf,Xaml,Mvvm,Treeview,我正在尝试构建一个包含三层的WPF树视图。CountryReportTitle是一个字符串属性,ArticleCategoryTitleList是一个集合,两者都从我的ViewModel中公开。没有定义类层次结构。这就是我正在寻找的结构: 这是我尝试的Xaml,但在运行时Xaml中出现异常: {"Item has already been added. Key in dictionary: 'DataTemplateKey(ISESApp.ViewModels.ReportViewModel)'

我正在尝试构建一个包含三层的WPF树视图。CountryReportTitle是一个字符串属性,ArticleCategoryTitleList是一个集合,两者都从我的ViewModel中公开。没有定义类层次结构。这就是我正在寻找的结构:

这是我尝试的Xaml,但在运行时Xaml中出现异常:

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


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

您需要在您的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绑定,而不是使用字符串列表


下面是一个很好的

您需要在您的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绑定,而不是使用字符串列表


这是一个很好的

这是我为TreeView准备的示例

对树中的元素使用HierarchycalDataTemplate。请注意,有三个层,每个层都有自己的类型。这是为了方便起见,但您可以为树定义一种类型并使用一个模板或任何类型的组合。在树中使用不同的类型表示不同的内容使得使用模板非常方便

数据类

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; }
}
还有用户界面

 <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>
给你一个简单的树状视图


下面是我为TreeView准备的示例

对树中的元素使用HierarchycalDataTemplate。请注意,有三个层,每个层都有自己的类型。这是为了方便起见,但您可以为树定义一种类型并使用一个模板或任何类型的组合。在树中使用不同的类型表示不同的内容使得使用模板非常方便

数据类

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; }
}
还有用户界面

 <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>
给你一个简单的树状视图


谢谢我的两个收藏都在同一个viewModel中。我真的不想分门别类。如果是这样,我将如何定义数据类型?@Hardgraf让我们假设ItemsB在ViewModel上,而不在ItemA中。您必须为ItemA-ItemsSource={Binding DataContext.ItemsB,ElementName=root}绑定回HierarchycalDataTemplate中的ViewModel,确保为窗口指定一个x:Name=root,以便ElementName指向正确的位置。我想我就快到了。将问题更改为我的新Xaml,但仍然不确定如何为我的每个HierarchyCalDataTemplates引用正确的数据类型。@Hardgraf我不知道。你的问题不清楚发生了什么。你们说事情是错的,但你们并没有包括关于它是如何出错的信息,若有错误,等等。公平点。我目前的代码有问题。问题是直到运行时我才知道每个列表将包含什么,因此需要在运行时动态构建TreeView。我认为我的问题是在哪里设置数据类型-数据类型={x:Type local:ReportViewModel}我认为这不正确,但我不确定如何将每个Hierarchy数据模板绑定到ViewModel中的正确列表谢谢。我的两个收藏都在同一个viewModel中。我真的不想分门别类。如果是这样,我将如何定义数据类型?@Hardgraf让我们假设ItemsB在ViewModel上,而不在ItemA中。您必须为ItemA-ItemsSource={Binding DataContext.ItemsB,ElementName=root}绑定回HierarchycalDataTemplate中的ViewModel,确保为窗口指定一个x:Name=root,以便ElementName指向正确的位置。我想我就快到了。将问题更改为我的新Xaml,但仍然不确定如何为我的每个HierarchyCalDataTemplates引用正确的数据类型。@Hardgraf我不知道。你的问题不清楚发生了什么。你们说事情是错的,但你们并没有包括关于它是如何出错的信息,若有错误,等等。公平点。我目前的代码有问题。问题是直到运行时我才知道每个列表将包含什么,因此需要在运行时动态构建TreeView。我认为我的问题是在哪里设置数据类型-数据类型={x:Type local:ReportViewModel}我认为这不正确,但我不确定如何将每个HierarchicalDataTemplate绑定到viewModel中的正确列表