2013-11-21 2 views
0

У меня есть структура рекурсивных данных ниже, и я хотел бы привязать ее к древовидному представлению. Но я не могу определить, как указать шаблоны данных/иерархические шаблоны данных.WPF Treeview связывается с несколькими вложенными списками

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

У вас либо есть дерево типа MediaSequence, либо MediaItem, но вы не можете иметь оба в своем дереве. –

+0

Будет ли это работать, если вы будете использовать TemplateSelector ??? – user2799180

ответ

5

Хорошо позволяет решать это с точки зрения самых простых вещей, во-первых, и это должно помочь очистить свое мышление. Возможно, это не похоже на то, но у вас нет ничего более сложного, чем обычные, папки и файлы, которые мы обычно видим.

Так что, если мы начнем с концами деревьев первых, мы можем определить

<DataTemplate DataType="{x:Type local:MediaItem}"> 
    <TextBlock Text="item" /> 
</DataTemplate> 

Мы не какие-либо подпункты так его просто обычный шаблон.

Перемещение глубже в дерево Теперь у нас есть узлы MediaSequence, которые имеют как элементы, так и последовательности на них. Если бы мы могли рассматривать их как одну вещь?

Хорошо, если мы придерживаемся аналогий файловой системы, вы обнаружите, что DotNet определяет FileInfo s и DirectoryInfo s как производные базы 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> 

И если вам действительно нужно, чтобы вы можете определить корень, как что-то другое тоже, но на самом деле просто последовательность.

public class MediaContent : MediaSequence 
{ 
    ... 
} 
+0

Это отлично работает, спасибо большое. Мне просто нужно было изменить свойство children, чтобы сначала включить список в IMedia, прежде чем вызывать метод concat, он не будет компилироваться иначе. Я мог бы, конечно, изменить свои списки на тип IMedia, но я предпочитаю, чтобы тип был явным. – RobJohnson

Смежные вопросы