2016-09-27 4 views
0

私はユーザライブラリを表すいくつかのクラスを持っています。は、ファイルシステムと同様の階層をツリービューで表示します。一般的なものは

public class UserLibraryData 
{ 
    public IList<Node<UserDataEntry>> Nodes { get; private set; } 
    ... 
} 

public class Node<T> 
{ 
    public IList<Node<T>> SubNodes { get; private set; } 
    public IList<T> Entries { get; private set; } 
    public string Name { get; private set; } 
    ... 
} 

public class UserDataEntry 
{ 
    string ViewName { get; private set;} 
    ... 
} 

だから、フォルダ(ノード)とファイル(エントリー)を使ってファイルシステムのようなものです:彼らはこのようになります。

今、私はそのデータをTreeViewで表現したいと思います。私はそのDataContextとしてUserLibraryDataのインスタンスを持つXAMLファイルを書きました。

<TreeView ItemsSource="{Binding Nodes}"> 
     <TreeView.ItemTemplate> 
      <HierarchicalDataTemplate ItemsSource="{Binding SubNodes}"> 
       <TextBlock Text="{Binding Name}"/> 
      </HierarchicalDataTemplate> 
     </TreeView.ItemTemplate> 
    </TreeView> 

しかし、予想通り、それが唯一のノードとサブノード、ないエントリを示しています。TreeViewコントロールのために、私はこれを書きました。私は別の DataTemplateTreeViewTemplateに追加しようとしましたが、そのようなテンプレートは1つしか定義できません。

どのようにして各レイヤーのノードのエントリも表示できますか?

EDIT:

は、我々は次のようUserLibraryDataがあるとします。

Node1 -> contains Node2, Node3 and Entry1, Entry2 
Node2 -> contains Entry3, Entry4 
Node3 -> contains Node4 
Node4 -> contains Entry5 
Node5 -> contains nothing 

これである(すべてのノードが展開されている)私の予想される出力:

Node1 
    Node2 
     Entry3 
     Entry4 
    Node3 
     Node4 
      Entry5 
    Entry1 
    Entry2 
Node5 

EDIT2:

この回答https://stackoverflow.com/a/39721198/5333340は、Nodeクラスは一般的ではありませんでした。残念ながら、DataType="{x:Type ...}"は、他のSOスレッドから学んだように、汎用タイプを許可していません。一般的な回避策は、この

public class NodeUserDataEntry : Node<UserDataEntry> { ... } 

のような子クラスを作成し、NodeUserDataEntryによってNode<UserDataEntry>のすべての発生を置き換えることです。しかし、Nodeの汎用性を重視したコードがすでに作成されています。したがって、タイプをNode<UserDataEntry>からNodeUserDataEntryに変更することは、アプリケーション全体を再作成するようなものです。 UserLibraryDataの、Node<T>UserDataEntryというコードをそのまま残して、それをいくつかのコンバーター/ラッパーで保存するだけの別の方法はありませんか?

+0

'Entires'を' Nodes'の横のリストとして表示するか、 'Node:Entry'のようなsometingを表示しますか? – bit

答えて

1

私はあなたのデータ構造を取って、機能するために欠けているものを追加しました。

あなたの問題は... HierarchicalDataTemplateをビルドすると、2つのリストをItemsSourceとして選択することはできません。テンプレートSubNodesEntriesの両方をNodeから表示するように指定することはできません。

あなたTreeViewを構築できるようにするために、あなたはEntriesSubNodes両方のユニークなList含むオ​​ブジェクトを作成する必要があります。

私はそれをChildrensと呼びました。 (これをノードクラスに追加する)。

public List<object> Childrens 
    { 
     get 
     { 
      _childrens = new List<object>(); 
      foreach (var subNode in SubNodes) 
      { 
       _childrens.Add(subNode); 
      } 
      foreach (var userDataEntry in Entries) 
      { 
       _childrens.Add(userDataEntry); 
      } 
      return _childrens; 
     } 
     private set { _childrens = value; } 
    } 

この後、XAMLを変更する必要があります。

テンプレートをリソースとして宣言し、DataTypesのおかげで、実行時にテンプレートが解決されます。クラスNodeから

  • Name

    は、我々は示したいと思います。

  • ViewNameクラスEntryから。
  • SubnodesおよびEntriesNodeChildrensプロパティに含まれています。 (両方の以前のプロパティを公開する)。

    <Grid.Resources> 
    
        <HierarchicalDataTemplate DataType="{x:Type local:Node}" ItemsSource="{Binding Childrens}"> 
         <TextBlock Text="{Binding Name}"/> 
        </HierarchicalDataTemplate> 
    
        <DataTemplate DataType="{x:Type local:UserDataEntry}"> 
         <TextBlock Text="{Binding ViewName}"/> 
        </DataTemplate> 
    
    </Grid.Resources> 
    

あなたのDataContextは、あなたのクラスUserLibraryDataに設定されている、あなたのツリービューをこのように宣言する必要がと仮定:

<TreeView ItemsSource="{Binding Nodes}"/> 

そして、あなたはこの結果を持っている必要があります。

enter image description here

+0

私はまだそれを働かせることができません。まず、 'HierarchicalDataTemplate'に関して、コンパイラは、' Node'型はありますが(ネームスペースが正しいことを再確認しました)、タイプ 'Node'を見つけることができないと言います。これはおそらく私の 'Node'にデフォルトの(パラメータなしの)コンストラクタがないという事実と関係していますか?次に、2つのDataTeplateをTreeViewに配置することはできません。あなたは何とか 'Grid.Resources'でこれを行うことができました。しかし、あなたは 'TreeView'でこれらのリソースをどのように使うのですか? – Kjara

+0

Nodeのパラメータのないコンストラクタを追加しても、その型を見つけることができないと文句を言う... – Kjara

+0

それとも、私の実際のアプリケーションで 'Node'が一般的なのでしょうか?この場合、回避する方法はありますか?私は一般的な 'Node 'の非持続的な子クラスを定義することができますが、次にコードをたくさん変更しなければなりません。 – Kjara

0

別の回避方法が見つかりました:

  • Node<T>Childrensプロパティを追加します(回答https://stackoverflow.com/a/39721198/5333340)。

  • UserDataEntryのプロパティViewNameの名前をNameに変更してください。私のXAMLコードでHierarchicalDataTemplateDataType属性が設定されていないので

  • 変更HierarchicalDataTemplate

  • "{Binding Childrens}"から

ItemsSourceは、それが両方Node<T>UserDataEntryChildrensコレクションのすべての要素のために使用されています)、両方ともプロパティNameを持っているので、それらのすべてについて表示されます。

これは、コード内のすべての型を変更するよりはるかに簡単です。

まだ私は、既存のコードを変更する必要はなく、拡張するだけのソリューションに興味があります。

関連する問題