2017-08-29 14 views
-1

私はTreeViewをカスタムオブジェクトとともに使用しています。ネストされたタイプに応じて、カスタム読み込みメソッドを使用してTreeViewItemを読み込みます。

目標TreeViewItem.Expandedイベントで、私は遅延ロードを達成するために、ネストされたタイプに依存A.またはB.LoadChilds()を呼び出したいです。

モデル

public class A 
{ 
    public A() 
    { 
     Childs = new ObservableCollection<B>(); 
    } 
    public string Name {get; set; } 
    public ObservableCollection<B> Childs { get; set; } 
    public void LoadChilds(DBConnection connection) //Type is unimportant 
    { 
     // adding childs 
    } 
} 

public class B 
{ 
    public B() 
    { 
     Childs = new ObservableCollection<B>(); //Yes, rekursiv 
    } 
    public string Name {get; set; } 
    public ObservableCollection<B> Childs { get; set; } 
    public void LoadChilds(DBConnection connection) 
    { 
     // adding childs 
    } 
} 

MainWindow.xaml

<TreeView x:Name="Tree"> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type model:A}" ItemsSource="{Binding Childs}"> 
      <StackPanel Orientation="Horizontal" > 
       <TextBlock Text="{Binding Name}" /> 
      </StackPanel> 
     </HierarchicalDataTemplate> 
     <HierarchicalDataTemplate DataType="{x:Type model:B}" ItemsSource="{Binding Childs}"> 
      <StackPanel Orientation="Horizontal" > 
       <TextBlock Text="{Binding Name}" /> 
      </StackPanel> 
     </HierarchicalDataTemplate> 
    </TreeView.Resources> 
</TreeView> 

コードの後ろ

//Init 
List<A> ListOfAs = getAs(dbConnection); 
Tree.ItemsSource = ListOfAs; 

質問:私の目標を達成する最良の方法は何ですか?

+0

私のq単に「保留にする」と設定されたューザーは私を助けません。不明な点を言うだけです。特に、他の人がこの問題を理解しており、その解決策はすでに与えられています。 – Syrlia

答えて

1

は間違いなく「きれい」な方法があります - なしコードビハインドのイベントハンドラにビジネスロジックを記述すること。

は、そのプロパティにTreeViewItem.IsExpandedをバインドし、セッターでLoadChilds方法をトリガー、ビューモデルのクラスでIsExpandedブール紹介:

<TreeView x:Name="Tree"> 
    <TreeView.ItemContainerStyle> 
     <Style TargetType="TreeViewItem"> 
      <Setter Property="IsExpanded" Value="{Binding Path=IsExpanded, Mode=TwoWay}"/> 
     </Style> 
    </TreeView.ItemContainerStyle> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type model:A}" ItemsSource="{Binding Childs}"> 
      <StackPanel Orientation="Horizontal" > 
       <TextBlock Text="{Binding Name}" /> 
      </StackPanel> 
     </HierarchicalDataTemplate> 
     <HierarchicalDataTemplate DataType="{x:Type model:B}" ItemsSource="{Binding Childs}"> 
      <StackPanel Orientation="Horizontal" > 
       <TextBlock Text="{Binding Name}" /> 
      </StackPanel> 
     </HierarchicalDataTemplate> 
    </TreeView.Resources> 
</TreeView> 
public class A 
{ 
    public A() 
    { 
     // null is a placeholder. 
     // without any items TreeViewItem will not even show expander 
     // (Expand event won't work either) 
     Childs = new ObservableCollection<B>() { null }; 
    } 

    public string Name { get; set; } 

    private bool _isExpanded; 
    public bool IsExpanded 
    { 
     get 
     { 
      return _isExpanded; 
     } 
     set 
     { 
      _isExpanded = value; 
      // when node is expanded, RELOAD! 
      if (_isExpanded) 
       LoadChilds(); 
     } 
    } 

    public ObservableCollection<B> Childs { get; set; } 

    public void LoadChilds() 
    { 
     Childs.Clear(); 
     Childs.Add(new B() { Name = Guid.NewGuid().ToString() }); 
    } 
} 

Bは、本試験例ではほとんど同じですが、私はLoadChildsを想定します実際のアプリケーションでは論理は異なります

public class B 
{ 
    public B() 
    { 
     Childs = new ObservableCollection<B>() { null }; 
    } 

    public string Name { get; set; } 

    private bool _isExpanded; 
    public bool IsExpanded 
    { 
     get 
     { 
      return _isExpanded; 
     } 
     set 
     { 
      _isExpanded = value; 
      if (_isExpanded) 
       LoadChilds(); 
     } 
    } 

    public ObservableCollection<B> Childs { get; set; } 

    public void LoadChilds() 
    { 
     Childs.Clear(); 
     Childs.Add(new B() { Name = Guid.NewGuid().ToString() }); 
    } 
} 
1

あなたがインターフェイスを実装両方ABを定義し、このタイプに拡大TreeViewItemDataContextをキャストすることができます:

public interface ICommon 
{ 
    string Name { get; set; } 
    void LoadChilds(DBConnection connection); 
} 

public class A : ICommon 
{ 
    public class A() 
    { 
     Childs = new ObservableCollection<B>(); 
    } 
    public string Name { get; set; } 
    public ObservableCollection<B> Childs { get; set; } 
    public void LoadChilds(DBConnection connection) //Type is unimportant 
    { 
     // adding childs 
    } 
} 

public class B : ICommon 
{ 
    public class B() 
    { 
     Childs = new ObservableCollection<B>(); //Yes, rekursiv 
    } 
    public string Name { get; set; } 
    public ObservableCollection<B> Childs { get; set; } 
    public void LoadChilds(DBConnection connection) 
    { 
     // adding childs 
    } 
} 

private void TreeView_Expanded(object sender, RoutedEventArgs e) 
{ 
    TreeViewItem tvi = e.OriginalSource as TreeViewItem; 
    ICommon obj = tvi.DataContext as ICommon; 
    if (obj != null) 
     obj.LoadChilds(...); 

} 
+0

現在、私はそのようなことをしています。 「かわいい」方法がありますか?私はできるだけ多くの依存関係を避けたい。インターフェースは依存関係です。 – Syrlia

+1

"インタフェースは依存関係です"というよりむしろインタフェースが抽象です。いいえ、「きれいな」方法はありません。インターフェイスを実装していない場合は、DataContextをA *および* a * B *にキャストしようとする必要があります。 – mm8

関連する問題