Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.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
Wpf 如何在TreeView中显示嵌套关系_Wpf_Treeview_Hierarchicaldatatemplate - Fatal编程技术网

Wpf 如何在TreeView中显示嵌套关系

Wpf 如何在TreeView中显示嵌套关系,wpf,treeview,hierarchicaldatatemplate,Wpf,Treeview,Hierarchicaldatatemplate,努力在我的树视图中显示嵌套关系。以下是场景: 在数据库中,我有Category和Account表。每个类别可以有零个或多个子类别,因此此表与自身具有嵌套关系。每个类别/子类别中可以有零个或多个帐户,类别和帐户之间存在一对多关系。很简单,不是吗 在我的数据库之上,我有EDMX,其中包含类别和帐户实体,以及我上面提到的它们的关联。为了便于理解,我重命名了导航属性,以便类别中现在有ParentCategory、ChildCategories和Accounts属性 在EDMX之上,我有我的ViewMod

努力在我的树视图中显示嵌套关系。以下是场景:

在数据库中,我有Category和Account表。每个类别可以有零个或多个子类别,因此此表与自身具有嵌套关系。每个类别/子类别中可以有零个或多个帐户,类别和帐户之间存在一对多关系。很简单,不是吗

在我的数据库之上,我有EDMX,其中包含类别和帐户实体,以及我上面提到的它们的关联。为了便于理解,我重命名了导航属性,以便类别中现在有ParentCategory、ChildCategories和Accounts属性

在EDMX之上,我有我的ViewModel,它定义了一个名为AllCategories的公共属性。我的TreeView将绑定到此属性。我在启动时初始化此属性,如下所示:

using (MyEntities context = new MyEntities())
    Categories = context.Categories.Include(x => x.Accounts).ToList();
最后,我使用以下HierarchycalDataTemplate来显示这些内容:

 <HierarchicalDataTemplate DataType = "{x:Type local:Category}" ItemsSource = "{Binding Path=ChildCategories}">
  <TreeViewItem Header="{Binding Name}" ItemsSource="{Binding Accounts}" />
</HierarchicalDataTemplate>

<DataTemplate DataType = "{x:Type local:Account}">
  <TextBlock Text="{Binding Name}" />
</DataTemplate>
这运行良好,并在树中显示类别、子类别和帐户,但问题是子类别不仅显示在其父类别下,而且显示在根级别。这适用于所有深度的类别。我做错了什么

注意:如果我添加.Wherex=>!x、 在VM中,它仅显示根类别及其直接子级,而不显示其他内容

编辑 下面是它目前的样子。所有的事情都进展顺利,直到我手动添加了那条白线作为插图;与WPF无关。之后,子类别开始与其子类别重复。这个过程一直持续到叶子的子类别。我相信我知道这里发生了什么,但没有解决办法。作为参考,他提出了一个问题的解决方案,但他使用的是数据集,而我使用的是EF,无法将他的解决方案转化为我的场景


其思想是通过ObservableCollections连接您的业务数据,并使您的分层模板保持简单,这样treeview就不会显示重复的条目。 示例代码显示嵌套的viewmodel关系和相应的层次模板。为了简化,根是一个可观察集合,否则您需要在此处添加INotifyPropertyChanged,并在树视图中添加选择性ItemsSource绑定

<Window x:Class="MyWpf.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:MyWpf"
    Title="MainWindow" Height="350" Width="525">
<Window.Resources>
    <HierarchicalDataTemplate DataType = "{x:Type local:RootItem}" ItemsSource = "{Binding Path=Categories}">
        <TextBlock Text="{Binding Header}"></TextBlock>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate DataType = "{x:Type local:CatNode}" ItemsSource = "{Binding Path=Items}">
        <TextBlock Text="{Binding Header}"></TextBlock>
    </HierarchicalDataTemplate>
</Window.Resources>
<Grid>
    <TreeView ItemsSource="{Binding MyRoot}"/>
</Grid>
</Window>

namespace MyWpf
{
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        MyRoot = new ObservableCollection<RootItem>();
        MyRoot.Add(new RootItem());
    }
    public ObservableCollection<RootItem> MyRoot { get; set; }
}

public class RootItem
{
    public RootItem()
    {
        Categories = new ObservableCollection<CatNode>();
        Categories.Add(new CatNode { Header = "Cat1" });
        Categories[0].Items.Add("Item11");
        Categories[0].Items.Add("Item12");
        Categories.Add(new CatNode { Header = "Cat2" });
        Categories[1].Items.Add("Item21");
        Categories[1].Items.Add("Item22");
    }
    public string Header { get { return "Root"; }}
    public ObservableCollection<CatNode> Categories { get; set; }
}
public class CatNode
{
    public CatNode()
    {
        Items = new ObservableCollection<string>();
    }
    public string Header { get; set; }
    public ObservableCollection<string> Items { get; set; }
}
}

添加另一个包含类别而不是子类别的层次模板。这将是你树视图的根。@deafjeff:谢谢。你能告诉我它是什么样子吗?我不明白你的问题,截图会很有帮助的。此外,您以错误的方式使用HierarchycalDataTemplate,其中的根可视控件应该是标题,因此通常我们需要在该位置使用一些ContentControl,而不是像您当前使用的TreeViewItem那样的Items控件。每个类别都有一个子类别集合和一个帐户集合,那么,您希望如何在一个树状项下显示2个这些集合呢?看来你得先把它们合并起来。@KingKing:我加了一张当前事态的截图。再加上一个指向解决这个问题的codeproject文章的链接。确实非常优雅。我后来发现,我向任何想开始使用WPF TreeView和MVVM的人推荐。尽管那篇文章相当广泛,但基本思想与您阐述的相同。非常感谢。顺便说一句,我也是从那篇文章开始的-