2016-09-23 7 views
2

MVVMで2レベルの構造化データを表現する必要があります。データは次のようになり場合:直接リンクのない2レベルの構造化データのWPFバインド

public class ParentEntity 
{ 
    public ObservableCollection<ChildEntity> ChildsEntities { get; set; } = new ObservableCollection<ChildEntity>(); 
    public string Name { get; set; } 
} 

public class ChildEntity 
{ 
    public string Name { get; set; } 
    public int Value { get; set; } 
} 

その後、私はツリービューとの結合を作成します:

<TreeView x:Name="treeView"> 
    <TreeView.Resources> 

     <!--Template for ParentEntity--> 
     <HierarchicalDataTemplate DataType="{x:Type ParentEntity}" ItemsSource="{Binding ChildsEntities}"> 
      <TextBox Text="{Binding Name}"/> 
     </HierarchicalDataTemplate> 

     <!--Template for ChildEntity--> 
     <DataTemplate DataType="{x:Type ChildEntity}"> 
      <StackPanel Orientation="Horizontal"> 
       <TextBox Text="{Binding Name}"/> 
       <TextBox Text="{Binding Value}"/> 
      </StackPanel> 
     </DataTemplate> 

    </TreeView.Resources> 
</TreeView> 

ObservableCollection<ParentEntity> data = new ObservableCollection<ParentEntity>(); 
treeView.ItemsSource = data ; 

しかし、私は(ライブラリーからの)このような構造を持っている:

public class ParentEntity 
{ 
    public int UID { get; set; } 
    public string Name { get; set; } 
} 

public class ChildEntity 
{ 
    public int ParentUID { get; set; } 
    public string Name { get; set; } 
    public int Value { get; set; } 
} 

、それはどのようにする必要があります取り扱った?ありがとう。

+0

質問の最初の部分で説明した構造を提供するオブジェクトにエンティティをラップすることを検討しましたか? – vkluge

+0

はい、それは最初の考えでしたが、私はそれが正しいアプローチであるかどうかはわかりません。 – Feofilakt

+0

IValueConverterを使用して、対応する子オブジェクトを親に返すメソッドを呼び出すことができます。[here](http://stackoverflow.com/a/844946/4189791)参照してください。これは間違いなく "正しい"アプローチ。 – vkluge

答えて

0

私は本当にこれを推薦ないのですが、私は問題を解決しますあなたは XAML

<StackPanel x:Name="root"> 
     <StackPanel.DataContext> 
      <vm:MainWindowViewModel></vm:MainWindowViewModel> 
     </StackPanel.DataContext> 
     <Button Command="{Binding AddRoot}">Add</Button> 
     <TreeView Height="400"> 
      <TreeView.Resources > 
       <Style TargetType="{x:Type TreeViewItem}"> 
        <Setter Property="IsExpanded" Value="True"> 
        </Setter> 
       </Style> 
       <vm:HierarchicalDataConverter x:Key="HierarchicalDataConverter"/> 
       <HierarchicalDataTemplate x:Key="ParentEntityTemplate" DataType="{x:Type vm:ParentEntity}" > 
        <HierarchicalDataTemplate.ItemsSource> 
         <MultiBinding Converter="{StaticResource HierarchicalDataConverter}" Mode="TwoWay"> 
          <Binding Mode="OneTime"></Binding> 
          <Binding Path="DataContext.Items" ElementName="root" ></Binding> 
          <Binding Path="DataContext.Items.Count" ElementName="root" ></Binding> 
         </MultiBinding> 
        </HierarchicalDataTemplate.ItemsSource> 
        <StackPanel Orientation="Horizontal"> 
         <TextBlock Text="{ Binding Name }"></TextBlock> 
         <Button Command="{Binding DataContext.AddLeafe, ElementName=root}" CommandParameter="{Binding}">Add item</Button> 
        </StackPanel> 
       </HierarchicalDataTemplate> 
       <DataTemplate x:Key="ChildEntityTemplate" DataType="{x:Type vm:ChildEntity}"> 
        <TextBlock Text="{Binding Name}"></TextBlock> 
       </DataTemplate> 
      </TreeView.Resources> 
      <TreeView.ItemsSource> 
       <Binding Path="RootItems"/> 
      </TreeView.ItemsSource> 
      <TreeView.ItemTemplateSelector> 
       <vm:ItemTemplateSelector> 
       </vm:ItemTemplateSelector> 
      </TreeView.ItemTemplateSelector> 
     </TreeView> 
    </StackPanel> 

を持っているVMの名前空間

public class MainWindowViewModel : BindableBase 
    { 
     public ObservableCollection<object> Items { get; } = 
      new ObservableCollection<object>(new List<object>(new List<object> 
     { 
      new ParentEntity { UID = 1, Name = "Groop1" }, 
      new ChildEntity { ParentUID = 1, Name = "Item1" }, 
      new ParentEntity { UID = 2, Name = "Groop2" }, 
      new ChildEntity { ParentUID = 2, Name = "Item1" }, 
      new ChildEntity { ParentUID = 2, Name = "Item2" }, 
      new ChildEntity { ParentUID = 2, Name = "Item3" } 
     })); 

     public CollectionView RootItems { get; } 


     int count = 2; 
     public DelegateCommand AddRoot { get; } 

     public DelegateCommand<ParentEntity> AddLeafe { get; } 
     public MainWindowViewModel() 
     { 
      RootItems = new ListCollectionView(Items) { Filter = (item) => item is ParentEntity }; 

      AddRoot = new DelegateCommand(() => 
      { 
       Items.Add(new ParentEntity { UID = ++count ,Name= "Group"+count}); 
      }); 

      AddLeafe = new DelegateCommand<ParentEntity>((pe) => 
      { 
       Items.Add(new ChildEntity { ParentUID = pe.UID, Name = "Item" + count }); 
      }); 

     } 

    } 

    public class ParentEntity 
    { 
     public int UID { get; set; } 
     public string Name { get; set; } 
    } 

    public class ChildEntity 
    { 
     public int ParentUID { get; set; } 
     public string Name { get; set; } 
     public int Value { get; set; } 
    } 

    public class ItemTemplateSelector : DataTemplateSelector 
    { 
     public override DataTemplate 
      SelectTemplate(object item, DependencyObject container) 
     { 
      FrameworkElement element = container as FrameworkElement; 

      if (item is ParentEntity) 
      { 
       return element.FindResource("ParentEntityTemplate") as DataTemplate; 
      } 
      if (item is ChildEntity) 
      { 
       return element.FindResource("ChildEntityTemplate") as DataTemplate; 
      } 
      return null; 
     } 
    } 

    public class HierarchicalDataConverter : IMultiValueConverter 
    { 
     public object Convert(object[] value, Type targetType, object parameter, CultureInfo culture) 
     { 
      if (value[0] != null) 
      { 
       ParentEntity pe = value[0] as ParentEntity; 
       var items = value[1] as IEnumerable<object>; 

       return items.Where((item) => item is ChildEntity && (item as ChildEntity).ParentUID == pe.UID); 
      } 
      return null; 
     } 

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

これに伴う問題は、それがすべての子ノードを再作成するということです

関連する問題