【问题标题】:WPF Treeview Databinding Hierarchal Data with mixed typesWPF Treeview数据绑定混合类型的分层数据
【发布时间】:2010-09-09 01:31:00
【问题描述】:

我在使用 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

现在,我正在尝试将此关系数据绑定到树视图。我希望 TreeView 看起来与上述对象构造几乎相同。

到目前为止,我的 XAML 树视图如下所示:

  <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 模式,不想求助于使用后面的代码,但如果有必要的话。

【问题讨论】:

    标签: wpf treeview binding hierarchical-data hierarchicaldatatemplate


    【解决方案1】:

    由于您希望 TreeView 中的元素具有包含两个类别产品的子项列表,因此您将希望您的类别视图模型具有一个包含类别和产品的集合。例如,您可以使用 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。

    【讨论】:

    • 这是一个完美的解决方案,谢谢!就像其他人的注释一样,将集合容器添加到复合集合的顺序是它们在树视图中出现的顺序。如果您先添加类别,它们将出现在产品之前
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-12
    • 2011-03-16
    相关资源
    最近更新 更多