WPF Treeview绑定到多个嵌套列表

Rob*_*son 0 wpf treeview recursion datatemplate

我有下面的递归数据结构,我想将它绑定到树视图.但我无法弄清楚如何指定我的数据模板/分层数据模板.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

困难来了,因为每个节点可以包含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);
Run Code Online (Sandbox Code Playgroud)

那么,如何在WPF树视图中显示此数据?

<TreeView Margin="5" VerticalAlignment="Top" Grid.Row="1" ItemsSource="{Binding Media}">
Run Code Online (Sandbox Code Playgroud)

我尝试过以下但显然你不能为同一数据类型指定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>
Run Code Online (Sandbox Code Playgroud)

任何帮助表示感谢,谢谢

AlS*_*Ski 5

好吧,我们先从最简单的事情来解决这个问题,它应该有助于清除你的想法.它可能看起来不像它,但你真的没有比我们通常看到的普通文件夹和文件更复杂的东西.

因此,如果我们首先从树的末端开始,我们可以定义

<DataTemplate DataType="{x:Type local:MediaItem}">
  <TextBlock Text="item" />
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

我们没有任何子项,所以它只是一个普通的模板.

更深入到树中,我们现在拥有MediaSequences的节点,它们上面都有项目和序列.只要我们能把它们视为一件事吗?

好吧,如果我们坚持使用文件系统类比,你会发现DotNet将FileInfos和DirectoryInfos 定义为a base的推导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);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

然后,我们可以定义另一个模板

<HierarchicalDataTemplate DataType="{x:Type local:MediaSequence}" ItemsSource="{Binding Children}">
  <TextBlock Text="sequence" />
</HierarchicalDataTemplate>
Run Code Online (Sandbox Code Playgroud)

如果你真的需要,你可以将你的root定义为不同的东西,但它实际上只是一个序列.

public class MediaContent : MediaSequence
{
   ...
}
Run Code Online (Sandbox Code Playgroud)