我试图获取一个TreeView
来绑定我的集合,以便所有组显示嵌套的组,并且每个组将显示条目。
如何使用HierarchicalDataTemplate
,使TreeView
同时处理SubGroups和Entries集合?
组显示子组和条目:
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; }
}
}
测试数据:
namespace DrillDownView
{
public class TestData
{
public IList<Group> Groups = new List<Group>();
public void Load()
{
Group grp1 = new Group() { Key = 1, Name = "Group 1", SubGroups = new List<Group>(), Entries = new List<Entry>() };
Group grp2 = new Group() { Key = 2, Name = "Group 2", SubGroups = new List<Group>(), Entries = new List<Entry>() };
Group grp3 = new Group() { Key = 3, Name = "Group 3", SubGroups = new List<Group>(), Entries = new List<Entry>() };
Group grp4 = new Group() { Key = 4, Name = "Group 4", SubGroups = new List<Group>(), Entries = new List<Entry>() };
//grp1
grp1.Entries.Add(new Entry() { Key=1, Name="Entry number 1" });
grp1.Entries.Add(new Entry() { Key=2, Name="Entry number 2" });
grp1.Entries.Add(new Entry() { Key=3,Name="Entry number 3" });
//grp2
grp2.Entries.Add(new Entry(){ Key=4, Name = "Entry number 4"});
grp2.Entries.Add(new Entry(){ Key=5, Name = "Entry number 5"});
grp2.Entries.Add(new Entry(){ Key=6, Name = "Entry number 6"});
//grp3
grp3.Entries.Add(new Entry(){ Key=7, Name = "Entry number 7"});
grp3.Entries.Add(new Entry(){ Key=8, Name = "Entry number 8"});
grp3.Entries.Add(new Entry(){ Key=9, Name = "Entry number 9"});
//grp4
grp4.Entries.Add(new Entry(){ Key=10, Name = "Entry number 10"});
grp4.Entries.Add(new Entry(){ Key=11, Name = "Entry number 11"});
grp4.Entries.Add(new Entry(){ Key=12, Name = "Entry number 12"});
grp4.SubGroups.Add(grp1);
grp2.SubGroups.Add(grp4);
Groups.Add(grp1);
Groups.Add(grp2);
Groups.Add(grp3);
}
}
}
XAML:
<Window x:Class="DrillDownView.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TaskManager.Domain;assembly=TaskManager.Domain"
Title="Window2" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TreeView Name="GroupView" Grid.Row="0" Grid.Column="0" ItemsSource="{Binding}">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type local:Group}" ItemsSource="{Binding SubGroups}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:Entry}" ItemsSource="{Binding Entries}">
<TextBlock Text="{Binding Path=Name}" />
</HierarchicalDataTemplate>
</TreeView.Resources>
</TreeView>
</Grid>
</Window>
XAML.CS:
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
LoadView();
}
private void LoadView()
{
TestData data = new TestData();
data.Load();
GroupView.ItemsSource = data.Groups;
}
}
4条答案
按热度按时间dgiusagp1#
HierarchicalDataTemplate
是一种表示“这就是你渲染这种类型的对象的方式,这里有一个属性,可以探测它来找到这个对象下的子节点”的方式。因此,您需要一个属性来返回此节点的“children”。例如,(如果您无法使Group和Entry都从公共节点类型派生)
接下来,条目不需要
HierarchicalDataTemplate
,因为条目没有子条目。因此需要更改XAML以使用新的Items属性和DataTemplate
作为条目:这就是它的样子。
czq61nw12#
下面是Gishu的答案的另一种实现,它返回
IEnumerable
而不是IList
,并使用yield
关键字来简化代码:f0ofjuux3#
我想你是大部分的方式在那里...与一点点的返工,你应该得到这个工作相当容易...
我建议您创建一个基本抽象类(或接口,无论您喜欢哪个),并为Group和Entry类继承/实现它...
这样,就可以在Group对象中公开属性
^此时,您可以决定是否替换子组和条目的列表,或者只是将它们追加在一起并在属性getter中返回它们...
现在,您所需要的就是使用Group或Entry对象填充Children集合,当对象被放置在TreeView中时,
HierarchicalDataTemplate
将正确呈现。最后一个想法,如果Entry总是树的“底层”(即没有孩子),那么你不需要为Entry对象定义一个
HierarchicalDataTemplate
,一个DataTemplate
就足够了。希望这对你有帮助:)
goucqfw64#
这篇文章帮助我找到了解决同样问题的方法:https://www.pmunin.com/2012/02/xaml-binding-to-compositecollection.html
使用MultiBinding和CompositeCollectionConverter