.net - WPF TreeView - 使用嵌套集合和 "Static nodes"绑定(bind)到 ViewModel

标签 .net wpf data-binding mvvm treeview

我已经查看了有关 TreeView 数据绑定(bind)到嵌套集合的类似问题,并且我已经阅读了几篇关于此主题的“Josh 'n Bea”文章,但我的设计不同之处在于我有“静态”TreeViewItems用作嵌套集合项的可折叠容器。最好说明我在寻找什么。

鉴于这些 ViewModel 类:

namespace TreeViewSample
{
    public class ApplicationViewModel
    {
        public ApplicationViewModel() { Projects = new List<ProjectViewModel>(); }
        public IEnumerable<ProjectViewModel> Projects { get; set; }
    }

    public class ProjectViewModel
    {
        public ProjectViewModel() { Maps = new List<MapViewModel>(); }
        public string Name { get; set; }
        public IEnumerable<MapViewModel> Maps { get; set; }
    }

    public class MapViewModel
    {
        public MapViewModel() { Tables = new List<TableViewModel>(); }
        public string Name { get; set; }
        public IEnumerable<TableViewModel> Tables { get; set; }
    }

    public class TableViewModel
    {
        public TableViewModel() { Fields = new List<FieldViewModel>(); }
        public string Name { get; set; }
        public IEnumerable<FieldViewModel> Fields { get; set; }
    }

    public class FieldViewModel
    {
        public string Name { get; set; }
    }
}

这是我想要的结果:

enter image description here

任何人都可以帮我处理这个 TreeView 的 XAML 吗?我以为我明白了HierarchicalDataTemplates工作,但“静态”容器节点(“表”、“字段”、“ map ”)似乎让我感到困惑。

谢谢你,祝你有愉快的一天!

最佳答案

我认为你将不得不创建 HierarchicalDataTemplate s 也适用于“静态”节点。并且由于 HierarchicalDataTemplate 的 ItemsSource期望一个集合,您可以像这样在 Xaml 中创建这些集合

命名空间

xmlns:coll="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:sys="clr-namespace:System;assembly=mscorlib"

收藏品
<coll:ArrayList x:Key="MapCollection">
    <sys:String>Maps</sys:String>
</coll:ArrayList>
<coll:ArrayList x:Key="TableCollection">
    <sys:String>Tables</sys:String>
</coll:ArrayList>
<coll:ArrayList x:Key="FieldCollection">
    <sys:String>Fields</sys:String>
</coll:ArrayList>

此解决方案的问题在于,当您设置例如MapCollection 作为 HierarchicalDataTemplate 的 ItemsSource ,您将无法访问 Maps下一个级别的集合属性,因此您必须爬上可视树才能捕获它
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}},
                      Path=DataContext.Maps}"

使用这种方法,您的 HierarchicalDataTemplate s 可以是这样的
<!-- Field Templates -->
<HierarchicalDataTemplate x:Key="FieldsTemplate">
    <TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="FieldTemplate"
                          ItemTemplate="{StaticResource FieldsTemplate}"
                          ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}},
                                                Path=DataContext.Fields}">
    <TextBlock Text="{Binding}"/>
</HierarchicalDataTemplate>

<!-- Table Templates -->
<HierarchicalDataTemplate x:Key="TablesTemplate"
                          ItemTemplate="{StaticResource FieldTemplate}"
                          ItemsSource="{Binding Source={StaticResource FieldCollection}}">
    <TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="TableTemplate"
                          ItemTemplate="{StaticResource TablesTemplate}"
                          ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}},
                                                Path=DataContext.Tables}">
    <TextBlock Text="{Binding}"/>
</HierarchicalDataTemplate>

<!-- Map Templates -->
<HierarchicalDataTemplate x:Key="MapsTemplate"
                          ItemTemplate="{StaticResource TableTemplate}"
                          ItemsSource="{Binding Source={StaticResource TableCollection}}">
    <TextBlock Text="{Binding Name}"/>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate x:Key="MapTemplate"
                          ItemTemplate="{StaticResource MapsTemplate}"
                          ItemsSource="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeViewItem}},
                                                Path=DataContext.Maps}">
    <TextBlock Text="{Binding}"/>
</HierarchicalDataTemplate>

<!-- Project Template -->
<HierarchicalDataTemplate x:Key="ProjectDataTemplate"
                          ItemTemplate="{StaticResource MapTemplate}"
                          ItemsSource="{Binding Source={StaticResource MapCollection}}">
    <TextBlock Text="{Binding Path=Name}"/>
</HierarchicalDataTemplate>

TreeView
<TreeView Name="treeView"
          ItemTemplate="{StaticResource ProjectDataTemplate}"
          ItemsSource="{Binding Projects}"/>

关于.net - WPF TreeView - 使用嵌套集合和 "Static nodes"绑定(bind)到 ViewModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4980392/

相关文章:

.net - 使用 SolrNet 查询 Solr 时,查看请求的实际 Url 的最简单方法是什么?

.NET 性能 : Deep Recursion vs Queue

html - 有没有一种简单的方法可以让 dojo/dijit 工具包与 knockout observables 一起工作?

wpf - 当不是数据上下文时绑定(bind)到窗口 View 模型属性

我想将 DateTime 变量设置为 null 的 C# 新手

.net - Entity Framework 5.0 奇怪的问题

wpf - 将 TreeView 选择绑定(bind)到 ViewModel

c# - 数据绑定(bind)依赖属性到数据对象

c# - WPF 针对 .NET 4.5 但 Windows 要求在应用程序运行时安装 .NET 3.5

.net - 使用 View 中的只读依赖属性在 ViewModel 中设置属性