WPF TreeView HierarchicalDataTemplate-привязка к объекту с несколькими дочерними коллекциями
Я пытаюсь получить TreeView
чтобы привязать мою коллекцию так, чтобы все группы показывали вложенные группы, и каждая группа будет показывать запись.
как я могу использовать HierarchicalDataTemplate
так что TreeView
будет обрабатывать как подгруппы, так и коллекцию записей?
группы показывают, подгруппы и элементы:
Example:
Group1
--Entry
--Entry
Group2
--Group4
----Group1
------Entry
------Entry
----Entry
----Entry
--Entry
--Entry
Group3
--Entry
--Entry
объекты:
namespace TaskManager.Domain
{
public class Entry
{
public int Key { get; set; }
public string Name { get; set; }
}
}
namespace TaskManager.Domain
{
public class Group
{
public int Key { get; set; }
public string Name { get; set; }
public IList<Group> SubGroups { get; set; }
public IList<Entry> Entries { get; set; }
}
}
4 ответа:
A
HierarchicalDataTemplate
это способ сказать: "вот как вы визуализируете этот тип объекта, и вот свойство, которое можно исследовать, чтобы найти дочерние узлы под этим объектом"поэтому вам нужно одно свойство, которое возвращает "детей" этого узла. например (если вы не можете сделать группу и запись производными от общего типа узла)
public class Group{ .... public IList<object> Items { get { IList<object> childNodes = new List<object>(); foreach (var group in this.SubGroups) childNodes.Add(group); foreach (var entry in this.Entries) childNodes.Add(entry); return childNodes; } }
Далее вам не нужен
HierDataTemplate
для записи, так как запись не имеет детей. Поэтому XAML необходимо изменить, чтобы использовать новый Свойство items иDataTemplate
для участия:<TreeView Name="GroupView" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding}"> <TreeView.Resources> <HierarchicalDataTemplate DataType="{x:Type local:Group}" ItemsSource="{Binding Items}"> <TextBlock Text="{Binding Path=Name}" /> </HierarchicalDataTemplate> <DataTemplate DataType="{x:Type local:Entry}" > <TextBlock Text="{Binding Path=Name}" /> </DataTemplate> </TreeView.Resources> </TreeView>
и вот как это выглядит.
Я думаю, что вы большую часть пути там... с небольшим количеством переделок вы должны получить эту работу довольно легко...
Я бы предложил вам создать базовый абстрактный класс (или интерфейс, в зависимости от того, что вы предпочитаете) и наследовать/реализовать его как для группы, так и для класса ввода...
таким образом, вы можете предоставить свойство в пределах вашего объекта группы
public ObservableCollection<ITreeViewItem> Children { get; set; }
^на этом этапе вы можете принять решение, если это заменяет ваши списки подгрупп и записей, или просто добавляет их вместе и возвращает их в свойстве getter...
теперь все, что вам нужно, это заполнить коллекцию Children либо групповыми, либо входными объектами, а
HierarchicalDataTemplate
будет отображаться правильно, когда объекты помещаются в TreeView..одна последняя мысль, если запись всегда является "нижним уровнем" дерева (т. е. не имеет детей), то вам не нужно определять
HierarchicalDataTemplate
для объекта ввода aDataTemplate
хватит.надеюсь, это поможет :)
вот альтернативная реализация ответа Гишу, которая возвращает
IEnumerable
, а неIList
, и используетyield
ключевое слово для упрощения кода:public class Group { ... public IEnumerable<object> Items { get { foreach (var group in this.SubGroups) yield return group; foreach (var entry in this.Entries) yield return entry; } } }
этот пост помог мне при поиске решения для той же проблемы:http://blog.pmunin.com/2012/02/xaml-binding-to-compositecollection.html
с помощью MultiBinding и CompositeCollectionConverter..
/С Уважением Андерс