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 объектами Group или Entry и HierarchicalDataTemplate
будет отображаться правильно, когда объекты помещаются в TreeView..
одна последняя мысль, если запись всегда является "нижним уровнем" дерева (т. е. не имеет детей), то вам не нужно определять HierarchicalDataTemplate
для объекта ввода a DataTemplate
хватит.
надеюсь, это поможет :)
вот альтернативная реализация ответа Гишу, который возвращает 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..
/С Уважением Андерс