2015-03-11 2 views
0

Я пытаюсь создать WPF TreeView с тремя слоями. CountryReportTitle - это свойство струны, а ArticleCategoryTitlesList - это коллекция, выставленная с моего ViewModel. Не существует иерархии классов. Это структура, я ищу:Простая структура вложенных TreeView Xaml?

enter image description here

Это моя попытка Xaml, но я получаю исключение в Xaml во время выполнения:

{"Item has already been added. Key in dictionary: 'DataTemplateKey(ISESApp.ViewModels.ReportViewModel)' Key being added: 'DataTemplateKey(ISESApp.ViewModels.ReportViewModel)'"} 

Xaml:

 <TreeView ItemsSource="{Binding CountryReportTitle}"> 
        <TreeView ItemsSource="{Binding CountryReportTitle}"> 
         <TreeView.Resources> 
          <HierarchicalDataTemplate DataType="{x:Type local:ReportViewModel}" 
           ItemsSource="{Binding ArticleCategoryTitlesList}"> 
           <TextBlock Text="{Binding CategoryTitle}" /> 
          </HierarchicalDataTemplate> 
          <HierarchicalDataTemplate DataType="{x:Type local:ReportViewModel}" 
           ItemsSource="{Binding ArticleCatagoryTypesList}"> 
           <TextBlock Text="{Binding ArticleTitle}" /> 
          </HierarchicalDataTemplate> 
          <DataTemplate DataType="{x:Type local:ReportViewModel}"> 
           <TextBlock Text="{Binding ArticleTitle}" /> 
          </DataTemplate> 
         </TreeView.Resources> 
        </TreeView> 
       </TreeView> 

Местное: это пространство для имени на моем ViewModel:

xmlns:local="clr-namespace:MyApp.ViewModels" 

Что я делаю неправильно, что лучше всего подходит для этой проблемы?

ответ

2

Вот мой пример для древовидных изображений.

Используйте элементы изображения в дереве HierarchicalDataTemplate. Обратите внимание, что существует три слоя, и каждый слой является его собственным типом. Это удобно, но вы можете определить один тип и использовать один шаблон или любое сочетание типов для вашего дерева. Имея разные типы, различные вещи в дереве делают использование шаблонов чрезвычайно удобным.

Классы данных

public class ViewModel 
{ 
    public ObservableCollection<ItemA> ItemsA { get; set; } 
    public ViewModel() 
    { 
     ItemsA = new ObservableCollection<ItemA>(new[]{ 
      new ItemA{Name = "A one"}, 
      new ItemA{Name = "A Two"}, 
      new ItemA{Name = "A Three"}, 
     }); 
    } 
} 

public class ItemA 
{ 
    public ObservableCollection<ItemB> ItemsB { get; set; } 
    public string Name { get; set; } 
    public ItemA() 
    { 
     ItemsB = new ObservableCollection<ItemB>(new[]{ 
      new ItemB{Name = "B one"}, 
      new ItemB{Name = "B Two"}, 
      new ItemB{Name = "B Three"}, 
     }); 
    } 
} 
public class ItemB 
{ 
    public ObservableCollection<ItemC> ItemsC { get; set; } 
    public string Name { get; set; } 
    public ItemB() 
    { 
     ItemsC = new ObservableCollection<ItemC>(new[]{ 
      new ItemC{Name = "C one"}, 
      new ItemC{Name = "C Two"}, 
      new ItemC{Name = "C Three"}, 
     }); 
    } 
} 
public class ItemC 
{ 
    public string Name { get; set; } 
} 

И UI

<TreeView ItemsSource="{Binding ItemsA}"> 
      <TreeView ItemsSource="{Binding ItemsA}"> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type t:ItemA}" 
            ItemsSource="{Binding ItemsB}"> 
      <TextBlock Text="{Binding Name}" /> 
     </HierarchicalDataTemplate> 
     <HierarchicalDataTemplate DataType="{x:Type t:ItemB}" 
            ItemsSource="{Binding ItemsC}"> 
      <TextBlock Text="{Binding Name}" /> 
     </HierarchicalDataTemplate> 
     <DataTemplate DataType="{x:Type t:ItemC}"> 
      <TextBlock Text="{Binding Name}" /> 
     </DataTemplate> 
    </TreeView.Resources> 
</TreeView> 

дает вам простой TreeView

enter image description here

+0

Спасибо. Обе мои коллекции находятся в одном представленииModel. Я действительно не хочу разделяться на разные классы. Если да, то каким образом я могу определить DataType? – Hardgraf

+0

@ Hardgraf Предположим, что ItemsB находится на ViewModel, а не в ItemA. Вам нужно будет привязать обратно к ViewModel в HierarchicalDataTemplate для ItemA - 'ItemsSource =" {Binding DataContext.ItemsB, ElementName = root} ", убедившись, что ваше окно« x: Name = »root» 'so что ElementName указывает на нужное место. – Will

+0

думаю, что я почти там. Изменил вопрос на мой новый Xaml, но все еще не уверен, как ссылаться на правильные типы данных для каждого из моих HierarchicalDataTemplates. – Hardgraf

3

Вы должны связать TreeView ресурсы внутри TreeView:

<TreeView.Resources> 
    <HierarchicalDataTemplate 
     DataType="{x:Type local:FirstLayer}" 
     ItemsSource="{Binding Children}"> 
     <StackPanel Orientation="Horizontal" Margin="2"> 
      <TextBlock Text="{Binding ChildrenName}" /> 
     </StackPanel> 
    </HierarchicalDataTemplate> 
    <HierarchicalDataTemplate 
     DataType="{x:Type local:SecondLayer}" 
     ItemsSource="{Binding Children}"> 
     <StackPanel Orientation="Horizontal" Margin="2"> 
      <TextBlock Text="{Binding ChildrenName}" /> 
     </StackPanel> 
    </HierarchicalDataTemplate> 
</TreeView.Resources> 

Я думаю, что вам нужно изменить свой проект, чтобы связать ваш Treeview с ViewModel вместо списка строки

Здесь является хорошим Example

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