Как сгруппировать дочерние объекты из одного списка в TreeView?

Как мне взять список, а затем в TreeView сгруппировать их по классу? Я читал это, но он не группирует дочерние объекты, он просто имеет связанные свойства в коллекциях.

  • Склад
    • Наберите "А
      • Подтип 1
      • Подтип 2
    • Тип Б
    • Тип С

Если у меня есть список, в котором есть все эти типы, как мне показать группировку в TreeView?

Раньше я добавлял их вручную по одному TreeViewItem за раз.

List<Warehouse> myWarehouse = new List<Warehouse>();
TreeViewItem WarehouseNode = new TreeViewItem() { Header = "Warehouse" };
TreeViewItem TypeANode = new TreeViewItem() { Header = "Type A" };
foreach(SubtypeA type in myWarehouse) {
    TypeANode.Items.Add(new TreeViewItem() { Header = type.Name };
}
WarehouseNode.Items.Add(TypeANode);
etc. for Type B and Type C.

Я читал о HierarchicalDataTemplate, и похоже, что именно так я и хочу, используя ItemTemplateSelector для изменения DataTemplate.

Итак, я начал работать с HierarchicalDataTemplates и придумал ниже.

XAML:

<Window.Resources>
    <Utility:MyTemplateSelector x:Key="MyTemplateSelector" />
    <HierarchicalDataTemplate x:Key="TypeCTemplate" DataType="{x:Type EntityType:TypeC}"
                              ItemsSource="{Binding OBJS}" ItemTemplateSelector="{StaticResource MyTemplateSelector}">
        <TextBlock Text="Type C"/>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate x:Key="TypeBTemplate" DataType="{x:Type EntityType:TypeB}"
                              ItemsSource="{Binding OBJS}" ItemTemplateSelector="{StaticResource MyTemplateSelector}">
        <TextBlock Text="Type B"/>
    </HierarchicalDataTemplate>
    <HierarchicalDataTemplate x:Key="TypeATemplate" DataType="{x:Type EntityType:TypeA}"
                              ItemsSource="{Binding OBJS}" ItemTemplateSelector="{StaticResource MyTemplateSelector}">
        <TextBlock Text="Type A"/>
    </HierarchicalDataTemplate>
</Window.Resources>
<Grid>
    <TreeView Name="MyTreeView" ItemsSource="{Binding OBJS}" 
              ItemTemplateSelector="{StaticResource MyTemplateSelector}">
    </TreeView>
</Grid>

Я написал DataTemplateSelector:

class MyTemplateSelector : DataTemplateSelector {
    public override DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container) {
        MethodInfo mi = container.GetType().GetMethod("FindResource") as MethodInfo;
        if(mi != null) {
            string strItem = item.ToString().Split('.').Last();
            switch(item.ToString().Split('.').Last()) {
                case "Type A":
                    return mi.Invoke(container, new object[] { "TypeATemplate" }) as DataTemplate;
                case "Type B":
                    return mi.Invoke(container, new object[] { "TypeBTemplate" }) as DataTemplate;
                case "Type C":
                    return mi.Invoke(container, new object[] { "TypeCTemplate" }) as DataTemplate;
            }

            return null;
        }

        return null;
    }
}

Но теперь, когда я смотрю на TreeView, он дает мне это:

  • Тип Б
  • Тип Б
  • Тип Б
  • Тип С
  • и т.п.

1 ответ

Сгруппируйте свою коллекцию, установив GroupDescription в ее CollectionViewSource. Вы можете сделать это в коде, выполнив что-то вроде этого:

CollectionViewSource.GetDefaultView(yourCollection).GroupDescriptions.Add(
new PropertyGroupDescription("PropertyName"));

Или вы можете сделать это в XAML, явно создав CollectionViewSource.

<CollectionViewSource
    Source="{StaticResource yourCollection}"
    xmlns:dat="clr-namespace:System.Windows.Data;assembly=PresentationFramework">
    <CollectionViewSource.GroupDescriptions>
        <dat:PropertyGroupDescription PropertyName="PropertyName"/>
    </CollectionViewSource.GroupDescriptions>
</CollectionViewSource>

Также проверьте это, введите описание ссылки здесь

Другие вопросы по тегам