2016-04-26 43 views
1

我有兴趣创建一个嵌套内容控件系统,以可视地表示用户在自动化系统中创建的节点网络。使用MVVM嵌套动态内容控件

简单地说,我有节点'x',它们每个都包含模块'y',它们承载着通道'z'。

到目前为止,我已经在ViewModel中建立了一个用于实例化所有这些的系统。 我有一个List<x>其中x是包含List<y>的模型(和属性:名称,ID), 其中y是包含List<z>一个模型(和属性:名称,索引),其中z为信道的模型(属性:名称,状态,命令)。

我想现在在我的视图中显示这些。

我想要这样做是如下,为每个模型xList<x>应该有其项 - 源是在该模型中的x一个List<y>带标题内容控制(或一些其它控制)方式。内容控制还应显示x的“名称”属性。

本内容控制下的每个y的数据模板应该是一个类似的内容控件,其中该模型y中的项目源是List<z>。内容控制还应显示y的“名称”属性。

最后,此内容控件下的每个模型z应该显示为一个CheckBox,它将它的“缺血”状态绑定到模型的'state'属性,它的内容属于'name'属性,它是'命令'属性。

我的问题是;有没有办法在MVVM中做到这一点?如果是这样,我该如何设置它?

+0

我想你只需要制作一个特殊的UserControl,它将具有ViewModel DataContext,通过它你可以绑定这三个列表,例如'' – 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 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> 

此处,对每类模板由ItemTemplate性质明确定义相应ItemsControl。我使用Margin属性来嵌套项目来引入一些缩进。

注意

我把它换成xyz类名与NodeModuleChannel分别可读性的原因。此外,我正在使用相应的集合名称 - Nodes,ModulesChannels - 我相信这应该是不言自明的。

+0

这就是方法比我实际做到的方式更简单。我还没有测试这种变化,但我相信它会起作用并且是最有效的方法。好奇;我做的方式是在ViewModel中为每个类创建HeaderedContentControl对象,并让视图显示链中的第一个。 –