我有下面的递归数据结构,我想将它绑定到树视图。但我无法弄清楚如何指定我的数据模板/分层数据模板。
public class MediaContent
{
public MediaContent()
{
this.Sequences = new List<MediaSequence>();
this.Items = new List<MediaItem>();
}
public List<MediaSequence> Sequences
{
get;
set;
}
public List<MediaItem> Items
{
get;
set;
}
}
public class MediaSequence
{
public MediaSequence()
{
this.Sequences = new List<MediaSequence>();
this.Items = new List<MediaItem>();
}
public List<MediaSequence> Sequences
{
get;
set;
}
public List<MediaItem> Items
{
get;
set;
}
}
public class MediaItem
{
public string Filename
{
get;
set;
}
}
困难来了,因为每个节点可以包含2个列表,并且列表是递归的。示例数据如下所示。
var uberNestedSequence = new MediaSequence();
uberNestedSequence.Items.Add(new MediaItem { Filename = "video1.mp4" });
uberNestedSequence.Items.Add(new MediaItem { Filename = "video2.avi" });
var nestedSequence = new MediaSequence();
nestedSequence.Sequences.Add(uberNestedSequence);
var nestedSequence2 = new MediaSequence();
this.Media.Sequences.Add(nestedSequence);
this.Media.Sequences.Add(nestedSequence2);
那么,如何在WPF树视图中显示这些数据?
<TreeView Margin="5" VerticalAlignment="Top" Grid.Row="1" ItemsSource="{Binding Media}">
我已尝试过以下内容,但显然您无法为同一数据类型指定2个不同的模板。
<HierarchicalDataTemplate DataType="{x:Type local:MediaSequence}" ItemsSource="{Binding Sequences}">
<TextBlock Text="sequence" />
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type local:MediaSequence}" ItemsSource="{Binding Items}">
<TextBlock Text="item" />
</HierarchicalDataTemplate>
感谢任何帮助,谢谢
答案 0 :(得分:5)
好吧,我们先从最简单的事情来解决这个问题,这应该有助于清除你的想法。它可能看起来不像它,但你没有比我们通常看到的普通文件夹和文件更复杂的东西。
因此,如果我们首先从树的末端开始,我们可以定义
<DataTemplate DataType="{x:Type local:MediaItem}">
<TextBlock Text="item" />
</DataTemplate>
我们没有任何子项,所以它只是一个普通的模板。
向树深处移动,我们现在拥有MediaSequence
个节点,这些节点上有项目和序列。如果我们只把它们视为一件事?
如果我们坚持使用文件系统类比,您会发现DotNet将FileInfo
和DirectoryInfo
定义为基础FileSystemInfo
的派生。我们所需要做的就是一样。
public interface IMedia
{
// Actually they have nothing in common
}
public class MediaItem : IMedia
{
...
}
public class MediaSequence : IMedia
{
public IEnumerable<IMedia> Children
{
get
{
// This one collection can now expose both types
// but can be anything behind the scenes
return Sequences.Concat(Items);
}
}
}
然后允许我们定义另一个模板
<HierarchicalDataTemplate DataType="{x:Type local:MediaSequence}" ItemsSource="{Binding Children}">
<TextBlock Text="sequence" />
</HierarchicalDataTemplate>
如果你真的需要,你可以将你的root定义为不同的东西,但它实际上只是一个序列。
public class MediaContent : MediaSequence
{
...
}