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

8
我正在尝试让我的树形视图通过它们的类型将一组相似的项目分组。为了保持通用性,我的对象层次结构可能是这样的:
Objects Object Group #1 Item #1 (类型 'A') Item #2 (类型 'A') Item #3 (类型 'B') Item #4 (类型 'B')
现在我的TreeView完全按照对象模型显示这些对象,但我想为每种对象类型插入一个TreeView节点,使其看起来像这样:
Objects Object Group #1 类型 A Item #1 Item #2 类型 B Item #3 Item #4
我在类似的问题中看到有人建议使用两个不同的HierarchicalDataTemplates,因此我为“Object Group #1”级别创建了一个模板,其中包含具有类型列表的TreeView,但这非常笨拙,因为它是一整个单独的TreeView在一些节点内部。我还尝试使用CollectionViewSource来过滤每个类别中的项目,但由于我无法弄清如何显示它们,这对我没有太大帮助。
我想问的问题归结为:如何使HierarchicalDataTemplate分组其子项?如果有人能指点我正确的方向,我将不胜感激。
如果有需要,我可以发布一些代码,但我真的只是想弄清楚如何做我想做的事情,因此我的代码现在只是一个相当直接的数据绑定树形视图。
4个回答

7
您可以通过在HierarchicalDataTemplate上绑定ItemsSource,并使用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 = g.Key, Items = g }
  }
  ...
}

现在您的HierarchicalDataTemplate可以如下所示:
<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
选择新建对象 { Type = item.Type, Items = g }; 无法编译;也许应该改为 select new { Type = g.First().Type, Items = g }; - arolson101
集合视图源是否更为合适? - BenKoshy

7
请看这篇Sumi先生的文章:这里。我相信这会对您有所帮助。
文章的主要内容如下:
解决这个问题的方法需要以下几个步骤:
  • 使用MultiBinding,允许您组合不同的绑定。
  • 使用转换器将不同的绑定集合组织成必要的子文件夹。
  • 当然,还需要数据模板来提供绑定数据的视觉表示。

0
如果您正在寻找一个简单的分组方法来显示扁平集合,也许使用“CollectionViewSource”会更合适。使用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}"
... />

0
据我所知,HierarchicalDataTemplate 无法对其子项进行分组。
视图应该只显示它所接收到的内容,而不需要深入了解对象种类/分组...为什么不在您的对象模型中创建这些分组呢?
然后视图将只会得到类似以下的东西:
public interface ITreeNode
{
    string Title;
    IList<ITreeNode> ChildNodes;  
}

并使用HierarchicalDataTemplate进行显示。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接