WPF Treeview数据绑定(bind)混合类型的分层数据

标签 wpf treeview binding hierarchical-data hierarchicaldatatemplate

WPF Treeview Binding 的情况有点复杂。我花了两天时间尝试谷歌它,this是我想出的关闭,但它不能解决问题。
情况如下:
我有一个看起来像这样的对象:

public class Category
{
  public string Name { get; set; }
  public List<Category> Categories { get; set; }
  public List<Product> Products { get; set; }
}

public class Product
{
  public string Name { get; set;
}
每个类别可以有一个对象列表和子类别。我有这样做的理由,这对我和我正在编写的应用程序来说完全有意义。
实际的对象构造可能看起来像这样:
Category - Pharmacy
  |-Product - Aspirin
  |-Product - Tylenol
  |-Category - Tooth Paste
  |  |-Product - Crest
  |  |-Product - Colgate
  |-Category - Paper Products
   |-Category - Toilet Paper
   |  |-Product - NoName
   |  |-Product - Charmin
   |-Category - Facial Tissue
      |-Product - Kleenex
Category - Household
  |-Product - Pinesol Cleaner
  |-Product - Garbage Bags
现在,我正在尝试将这种关系数据绑定(bind)到 TreeView 。我希望 TreeView 看起来与上述对象构造几乎相同。
到目前为止,我的 XAML Treeview 看起来像这样:
  <TreeView x:Name="CategoryList" Margin="8" Grid.Row="2" Grid.RowSpan="2" ItemsSource="{Binding Path=Categories}">
            <TreeView.Resources>
                <HierarchicalDataTemplate DataType="{x:Type src:Category}" ItemsSource="{Binding Products}">
                    <StackPanel>
                        <TextBlock Text="{Binding Path=Name}" />
                    </StackPanel>
                </HierarchicalDataTemplate>
                <HierarchicalDataTemplate DataType="{x:Type src:Product}">
                    <StackPanel>
                        <TextBlock Text="{Binding Path=Name}" />
                    </StackPanel>
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>
这适用于主要类别列表及其每个子产品。但它并没有更深入地显示每个类别下的子类别。
有没有办法直接使用模板来执行此操作,以便选择每个项目(类别或产品)?我正在使用 MVVM 模式,不想求助于使用后面的代码,但如果有必要的话。

最佳答案

由于您希望 TreeView 中的元素具有包含两个类别产品的子项列表,因此您将希望类别 View 模型具有一个包含类别和产品的集合。例如,您可以使用 CompositeCollection合并您现有的收藏:

public class Category
{
    public string Name { get; set; }
    public List<Category> Categories { get; set; }
    public List<Product> Products { get; set; }

    public IList Children
    {
        get
        {
            return new CompositeCollection()
            {
                new CollectionContainer() { Collection = Products },
                new CollectionContainer() { Collection = Categories }
            };
        }
    }
}

(在实际代码中,您可能希望保留对同一集合对象的引用,而不是每次都创建一个新对象。)

然后在您的 HierarchicalDataTemplate 中,使用组合列表作为 ItemsSource:
<HierarchicalDataTemplate DataType="{x:Type src:Category}"
                          ItemsSource="{Binding Children}">

这些项目将是 Product 和 Category 对象的混合,WPF 将为每个对象使用适当的 DataTemplate。

关于WPF Treeview数据绑定(bind)混合类型的分层数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3673173/

相关文章:

c# - WPF/RibbonGallery : Need help understanding binding and events

c# - 筛选 TreeView 节点的最佳方式

c++ - 如何使 Qt 快速导航树项目?

c# - 将文本 block 绑定(bind)到两个属性

c# - ContentControl 内容属性不随托管内容而改变

c# - 更改项目时的 WPF 列表框选择问题

c# - 如何在根节点 [TreeView] 找到子节点

c# - 绑定(bind)不正确更新 usercontrol 属性 MVVM

xml - 尝试解码时出现 SAXParseException

wpf - 您如何知道您的 WPF 控件是否正在呈现?