2015-01-16 8 views
0

Я сижу с проблемой, где у меня есть два отдельных ObservableCollection в ViewModel. Один список содержит следующий объект:Создайте дерево из двух отдельных списков, где дочерние объекты имеют идентификатор родителя

public class TypeCategory { 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Description { get; set; } 
} 

Другой список является:

public class Type { 
    public string Name { get; set; } 
    public string Description { get; set; } 
    public int CategoryId { get; set; } 
} 

ViewModel, как:

public class TheViewModel { 
    public ObservableCollection<TypeCategory > TypeCategories { get; private set; } 
    public ObservableCollection<Type> Types { get; private set; } 
} 

Type является childNode к TypeCategory, где соединение к родительскому узлу - CategoryId. Можно ли сгенерировать TreeView, используя, например, multibinding и конвертер для соединения двух списков? Или это единственное решение для расширения родительского класса, чтобы содержать его детей?

ответ

1

Вы можете попробовать так:

Использование Dictionary<string,List<string>>, которые трюма TypeCategory Name в Key & List<string>, который содержит под этим Category.

public class TheViewModel 
{ 
    public ObservableCollection<TypeCategory> TypeCategories { get; set; } 
    public ObservableCollection<Type> Types { get; set; } 
    public Dictionary<string,List<string>> TreeViewItemSource { get; set; } 

    public TheViewModel() 
    { 
     TypeCategories = new ObservableCollection<TypeCategory>(); 
     Types = new ObservableCollection<Type>(); 
     TreeViewItemSource = new Dictionary<string, List<string>>(); 

     for (int i = 0; i < 10; i++) 
     { 
      TypeCategories.Add(new TypeCategory() { Id = i, Name = "TypeCategory "+ i, Description = string.Empty }); 
     } 

     for (int i = 0; i < 50; i++) 
     { 
      Types.Add(new Type() { CategoryId = i/5, Name = "Type " + i, Description = string.Empty }); 
     } 

     foreach (TypeCategory item in TypeCategories) 
     { 
      List<string> list = Types.Where(p => p.CategoryId == item.Id).Select(p=>p.Name).ToList<string>(); 
      TreeViewItemSource.Add(item.Name, list); 
     } 
    } 
} 

XAML:

<TreeView Name="treeView1" ItemsSource="{Binding TreeViewItemSource}" > 
    <TreeView.ItemTemplate> 
     <HierarchicalDataTemplate ItemsSource="{Binding Path=Value}"> 
      <TextBlock FontWeight="Bold" Text="{Binding Path=Key}" /> 
      <HierarchicalDataTemplate.ItemTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding }"/> 
       </DataTemplate> 
      </HierarchicalDataTemplate.ItemTemplate> 
     </HierarchicalDataTemplate> 
    </TreeView.ItemTemplate> 
</TreeView> 

Надеется, что это поможет.

UPDATE:

Если вы не хотите, чтобы создать словарь, то вам нужно применить MultiBinding на HierarchicalDataTemplate's ItemSource.

xmlns:local="clr-namespace:assembly_Name" 
..... 
<TreeView Name="treeView1" ItemsSource="{Binding TypeCategories}" Tag="{Binding Types}"> 
    <TreeView.Resources> 
     <local:CategoryItemsConverter x:Key="CategoryItemsConverter"/> 
    </TreeView.Resources> 
    <TreeView.ItemTemplate> 
     <HierarchicalDataTemplate > 
      <HierarchicalDataTemplate.ItemsSource> 
       <MultiBinding Converter="{StaticResource CategoryItemsConverter}"> 
        <Binding Path="Tag" ElementName="treeView1"/> 
        <Binding Path="ItemsSource" ElementName="treeView1"/> 
        <Binding Path="Name"/> 
       </MultiBinding> 
      </HierarchicalDataTemplate.ItemsSource> 
      <TextBlock FontWeight="Bold" Text="{Binding Name}" /> 
      <HierarchicalDataTemplate.ItemTemplate> 
       <DataTemplate> 
        <TextBlock Text="{Binding Name}"/> 
       </DataTemplate> 
      </HierarchicalDataTemplate.ItemTemplate> 
     </HierarchicalDataTemplate> 
    </TreeView.ItemTemplate> 
</TreeView> 

CategoryItemsConverter:

public class CategoryItemsConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, System.Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     ObservableCollection<Type> typesList = values[0] as ObservableCollection<Type>; 
     ObservableCollection<TypeCategory> categoryList = values[1] as ObservableCollection<TypeCategory>; 
     string currentCategory = values[2] as string; 
     if (typesList != null && categoryList != null && !string.IsNullOrEmpty(currentCategory)) 
     { 
      int? categoryId = categoryList.Where(p => p.Name == currentCategory).Select(p=>p.Id).FirstOrDefault(); 
      if (categoryId.HasValue) 
      { 
       var a = typesList.Where(p => p.CategoryId == categoryId).ToList<Type>(); 
       if (a.Any()) 
       { 
        return a; 
       } 
      } 
     } 
     return null; 
    } 

    public object[] ConvertBack(object value, System.Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 
+0

Это то, что я также думал делать, но было просто интересно, если можно было бы решить с помощью MultiBinding или какой-либо другое решение, не создавая дополнительный список? Это происходит только из-за недостатка знаний о ограничениях с привязками и XAML. –

+1

@dennis_ler Проверить обновленный ответ ... –

+0

Спасибо, что я пытался выяснить. –