Группировка дочерних объектов в WPF TreeView
Я пытаюсь получить представление дерева, чтобы сгруппировать коллекцию похожих элементов по тому, что они есть. Чтобы сохранить универсальность, моя иерархия объектов может выглядеть так:
- объекты
- Группа Объектов #1
- Пункт #1 (Тип 'A')
- Пункт #2 (Тип 'A')
- Пункт #3 (Тип 'B')
- Пункт #4 (Тип 'B')
- Группа Объектов #1
прямо сейчас мой TreeView показывает эти объекты точно такие же, как объектная модель, но я хотел бы вставить узел TreeView для каждого типа объекта, чтобы он выглядел так:
- объекты
- Группа Объектов #1
- Тип A
- пункт #1
- пункт #2
- Тип B
- п. 3
- пункт #4
- Тип A
- Группа Объектов #1
Я видел в похожем вопросе вот что кто-то рекомендовал иметь два отдельных HierarchicalDataTemplates
поэтому я создал один для уровня "Object Group #1", который содержит TreeView со списком типов, но это действительно неуклюже, так как это целый отдельный TreeView внутри некоторых узлов. Я также пытался использовать CollectionViewSource
чтобы отфильтровать элементы в каждой категории, но это не очень хорошо, так как я не могу понять, как их отображать.
Я думаю, мой вопрос сводится к следующему: как я сделайте группа это? Если бы кто-то мог указать мне в правильном направлении, я был бы очень признателен.
Я могу опубликовать некоторый код, если кто-то хочет видеть, но я действительно просто пытаюсь понять, как сделать то, что я хочу, поэтому мой код-это просто довольно прямой treeview базы данных прямо сейчас.
4 ответов
вы можете достичь этого эффекта, связав 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>
насколько я знаю, HierarchicalDataTemplate
не удается сгруппировать своих детей.
View должен просто отображать все, что он получает, не копаясь в видах / группах объектов... Почему бы вам не создать эти группы в объектной модели?
и вид будет просто получить smth, как:
public interface ITreeNode
{
string Title;
IList<ITreeNode> ChildNodes;
}
и отобразить его с помощью HierarchicalDataTemplate
.
Если это простой метод группировки из плоской коллекции для отображения цели, которую вы ищете, возможно, использование "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}"
... />