2016-04-26 20 views
1

私は、ネストされたコンテンツコントロールのシステムを作成して、オートメーションシステムのユーザー作成ネットワークノードを視覚的に表現したいと考えています。MVVMを使用したネストされた動的コンテンツコントロール

単純に、私はノード「x」を持ち、それらはそれぞれ、チャネル「z」をホストするモジュール「y」を含む。

これまで、私はViewModelでこれをすべてインスタンス化するためのシステムをセットアップしました。 (と属性:名前、インデックス)yList<z>を含むモデルである、 :(名前、IDおよび属性)zは、チャネルのモデルである(属性 私はxList<y>を含むモデルですList<x>を持っています:名前、状態、コマンド)。

これを私のビューに表示したいと思います。

次のように私はこれを実行したい方法は、List<x>における各モデルxため、そのアイテム・ソースこのモデルxList<y>あるヘッダー付きコンテンツコントロール(またはいくつかの他のコントロール)があるはずです。コンテンツコントロールには、「name」属性のxも表示されます。

このコンテンツコントロールの各yのデータテンプレートは、このモデルのList<z>である類似したコンテンツコントロールである必要がありますy。コンテンツコントロールには、「名前」属性yも表示されます。

最後に、このコンテンツコントロールの下の各モデルzは、モデルの '状態'属性に「ischecked」状態をバインドするCheckBoxとして表示され、 'name'属性の内容になります。 'コマンド'属性。

私の質問は、 MVVMでこれを行う方法はありますか?もしそうなら、私はそれをどうやって設定するのですか?

+0

私は、これらの3つのリストをバインドできるViewModel DataContextを持つ特別なUserControlを作成する必要があると思います。例えば、 ' – mikes

答えて

0

いつものように、このタスクを達成するにはいくつかの方法があります。達成したい視覚的な結果の種類に強く依存します。

あなたはツリーとして、あなたのデータを表示することができます

<TreeView ItemsSource="{Binding Nodes}"> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type local:Node}" 
            ItemsSource="{Binding Modules}"> 
      <TextBlock Text="{Binding Name}" /> 
     </HierarchicalDataTemplate> 
     <HierarchicalDataTemplate DataType="{x:Type local:Module}" 
            ItemsSource="{Binding Channels}"> 
      <TextBlock Text="{Binding Name}" /> 
     </HierarchicalDataTemplate> 
     <DataTemplate DataType="{x:Type local:Channel}"> 
      <CheckBox Content="{Binding Name}" 
         IsChecked="{Binding State}" 
         Command="{Binding Command}" /> 
     </DataTemplate> 
    </TreeView.Resources> 
</TreeView> 

この例では、あなたのクラスのためのネストされた項目の両方外観と関係がHierarchicalDataTemplate秒で定義されています。 TreeViewコントロールはそれらをどうするかを知るのに "スマート"です。各クラスのテンプレートはItemsControl対応にItemTemplateプロパティで明示的に定義される。ここ

<ItemsControl ItemsSource="{Binding Nodes}"> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <HeaderedContentControl Header="{Binding Name}"> 
       <ItemsControl ItemsSource="{Binding Modules}" 
           Margin="10,0,0,0"> 
        <ItemsControl.ItemTemplate> 
         <DataTemplate> 
          <HeaderedContentControl Header="{Binding Name}"> 
           <ItemsControl ItemsSource="{Binding Channels}" 
               Margin="10,0,0,0"> 
            <ItemsControl.ItemTemplate> 
             <DataTemplate> 
              <CheckBox IsChecked="{Binding State}" 
                 Content="{Binding Name}" 
                 Command="{Binding Command}" /> 
             </DataTemplate> 
            </ItemsControl.ItemTemplate> 
           </ItemsControl> 
          </HeaderedContentControl> 
         </DataTemplate> 
        </ItemsControl.ItemTemplate> 
       </ItemsControl> 
      </HeaderedContentControl> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

より一般的な解決策は、これらの線に沿って何かだろう。入れ子になった項目にはインデントを導入するためにMarginプロパティを使用しました。

NOTE

私は読みやすさのために、それぞれNodeModuleChannelxyzクラス名を交換しました。また、私は対応するコレクション名 - NodesModulesChannelsを使用しています - 私はそれが自明であるべきだと信じています。

+0

私が実際にやったよりも簡単です。私はこのバリエーションをまだテストしていませんが、それがうまくいくと確信しており、最も効率的な方法です。好奇心をそそる;私がやったやり方は、それぞれのクラスのViewModelにHeaderedContentControlオブジェクトを作成して、そのビューの最初にチェーンを表示させることでした。 –

関連する問題