在WPF TreeView中对子对象进行分组

时间:2010-02-11 22:41:51

标签: c# wpf xaml treeview hierarchicaldatatemplate

我正在尝试将树视图按照它们的类别对类似项目的集合进行分组。为了保持通用性,我的对象层次结构可能如下所示:

  • 物件
    • 对象组#1
      • 项目#1(类型'A')
      • 项目#2(类型'A')
      • 项目#3(类型'B')
      • 项目#4(类型'B')

现在我的TreeView显示这些对象与对象模型完全一样,但我想要做的是为每个对象类型插入一个TreeView节点,使它看起来像这样:

  • 物件
    • 对象组#1
      • A型
        • 项目#1
        • 项目#2
      • B型
        • 项目#3
        • 项目#4

我在这里看到一个类似的问题,有人建议有两个单独的HierarchicalDataTemplates所以我创建了一个'对象组#1'级别,其中包含一个带有类型列表的TreeView,但这真的很笨拙因为它是一些单独的TreeView内部的一些节点。我也一直在尝试使用CollectionViewSource过滤掉每个类别中的项目,但这对我来说并不是很好,因为我无法弄清楚如何显示它们。

我想我的问题归结为:我如何让HierarchicalDataTemplate组成为孩子?如果有人能指出我正确的方向,我会非常感激。

如果有人想看,我可以发布一些代码,但我真的只想弄清楚如何做我想要的,所以我的代码现在只是一个非常简单的数据绑定树视图。

4 个答案:

答案 0 :(得分:7)

您可以使用ItemsSource绑定HierarchicalDataTempalate IValueConverter来实现此效果。此转换器只是执行以下操作:

public class MyConverter : IValueConverter
{
  public object Convert(object value, ...)
  {
    return
      from item in (IEnumerable<MyItem>)value
      group item by item.Type into g
      select new { Type = item.Type, Items = g };
  }
  ...
}

现在您的HierarchcialDataTemplate可以如下:

<HierarchicalDataTemplate ItemsSource="{Binding SomePath, Converter={x:Static local:MyConverter}">

  <HierarchicalDataTemplate.ItemTemplate>
    <HierarchicalDataTemplate
      ItemsSource="{Binding Items}"
      TargetType="{x:Type local:MyItem}"

      ItemTemplate="{StaticResource MyItemTemplate}">
         <!-- may omit ItemTemplate in prior line to use implicit template -->

      <TextBlock Text="{Binding Type}" /> <!-- Header for type -->

    </HierarchicalDataTemplate>
  </HierarchicalDataTemplate.ItemTemplate>

  <!-- header for "Object Group #1" -->

</HierarchicalDataTemplate>

答案 1 :(得分:5)

看看Sumi先生的this文章。我相信它会对你有所帮助。

答案 2 :(得分:0)

AFAIK,HierarchicalDataTemplate无法将其子女分组。

View应该只显示它​​获得的内容,而不是真正挖掘对象种类/组...为什么不在对象模型中创建这些组?

视图就像是:

public interface ITreeNode
{
    string Title;
    IList<ITreeNode> ChildNodes;  
}

并使用HierarchicalDataTemplate显示它。

答案 3 :(得分:0)

如果这是一个来自Flat Collection的简单分组方法,用于显示目的,您正在寻找可能使用“CollectionViewSource”将更合适。由于Property / Collection Change事件传播,使用LINQ可能会成为一场噩梦。

<CollectionViewSource x:Key="GroupedItems" Source="{Binding ItemsSource,  ElementName=My_UserControl}">
    <CollectionViewSource.GroupDescriptions>
        <PropertyGroupDescription PropertyName="Type" Converter="{StaticResource GroupingConverter}" />
    </CollectionViewSource.GroupDescriptions>
    <CollectionViewSource.SortDescriptions>
        <scm:SortDescription PropertyName="Date"/>
    </CollectionViewSource.SortDescriptions>
</CollectionViewSource>

<HierarchicalDataTemplate x:Key="GroupDataTemplate"  ItemsSource="{Binding Items}" >
    <TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>

<TreeView x:Name="ItemHolder" x:FieldModifier="private"
    ItemsSource="{Binding Source={StaticResource GroupedItems}, Path=Groups}"
... />