29

我对WPF Treeview绑定有点复杂的情况。我花了最后2天尝试谷歌它,并且this是封闭的我想出了,但它不能解决问题。WPF Treeview数据绑定混合类型的分层数据

这里的情况是:

我有一个对象,看起来像这样:

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。我希望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模式,不想诉诸使用后面的代码,但如果有必要的话。

回答

46

由于您希望TreeView中的元素具有由两个Categories产品组成的子项列表,因此您希望Category ViewModel具有一个由类别和产品组成的集合。例如,你可以使用一个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}"> 

的项目将是产品和类别对象的混合,而WPF将使用相应的DataTemplate中的每一个。

+2

这是一个完美的解决方案,谢谢!就像其他人的说明一样,将集合容器添加到组合集合的顺序是它们在树形视图中显示的顺序。如果您先添加类别,它们会出现在产品之前 – thorkia 2010-09-09 13:54:34