2013-02-01 39 views
13

我有一個ObservableCollection,它包含多種類型的視圖模型,我想爲每個GridViewColumn的CellTemplates中的每個類型創建一個DataTemplate。在這個簡單的例子中,我可以創建一個基本的ViewModel,但我希望能夠通過xaml來完成。下面的xaml顯示了我正在嘗試做什麼,其中一個DataTemplates將用於每個CellTemplate。GridViewColumn中的每個DataType的DataTemplate CellTemplate

如果有一個GridViewColumn.Resources,我會在那裏定義DataTemplates,然後在CellTemplate中使用ContentPresenter的DataTemplate,但我顯然不能這樣做。我想我可能需要一個TemplateSelector,但我不知道從哪裏開始。

<ListView ItemsSource={Binding GenericObservableCollection> 
    <ListView.View> 
     <GridView> 
      <GridViewColumn Header="Type"> 
       <GridViewColumn.CellTemplate> 
        <DataTemplate DataType="{x:Type vm:ActionInputViewModel}"> 
         <TextBlock Text="Input"/> 
        </DataTemplate> 
        <DataTemplate DataType="{x:Type vm:ActionOutputViewModel}"> 
         <TextBlock Text="Output"/> 
        </DataTemplate> 
       </GridViewColumn.CellTemplate> 
      </GridViewColumn> 
      <GridViewColumn Header="Value"> 
       <GridViewColumn.CellTemplate> 
        <DataTemplate DataType="{x:Type vm:ActionInputViewModel}"> 
         <TextBlock Text="{Binding Property1}"/> 
        </DataTemplate> 
        <DataTemplate DataType="{x:Type vm:ActionOutputViewModel}"> 
         <TextBlock Text="{Binding Property2}"/> 
        </DataTemplate> 
       </GridViewColumn.CellTemplate> 
      </GridViewColumn> 
     </GridView> 
    </ListView.View> 
</ListView> 

回答

30

有幾種不同的方法可以到這裏。你可以寫一個DataTemplateSelector並分配到GridViewColumn.CellTemplateSelector屬性:

public class ViewModelTemplateSelector : DataTemplateSelector 
{ 
    public DataTemplate InputTemplate { get; set; } 
    public DataTemplate OutputTemplate { get; set; } 

    public override DataTemplate SelectTemplate(object item, DependencyObject container) 
    { 
     return (item is ActionInputViewModel) ? InputTemplate : OutputTemplate; 
    } 
} 

然後你可以移動的地方所有的模板資源 - 在這裏,我只是堅持它在ListView爲簡潔:

<ListView ItemsSource="{Binding GenericObservableCollection}"> 
     <ListView.Resources> 
      <DataTemplate x:Key="InLabel" DataType="{x:Type vm:ActionInputViewModel}"> 
       <TextBlock Text="Input"/> 
      </DataTemplate> 
      <DataTemplate x:Key="OutLabel" DataType="{x:Type vm:ActionOutputViewModel}"> 
       <TextBlock Text="Output"/> 
      </DataTemplate> 
      <DataTemplate x:Key="InValue" DataType="{x:Type vm:ActionInputViewModel}"> 
       <TextBlock Text="{Binding Property1}"/> 
      </DataTemplate> 
      <DataTemplate x:Key="OutValue" DataType="{x:Type vm:ActionOutputViewModel}"> 
       <TextBlock Text="{Binding Property2}"/> 
      </DataTemplate> 
     </ListView.Resources> 
     <ListView.View> 
      <GridView> 
       <GridViewColumn Header="Type"> 
        <GridViewColumn.CellTemplateSelector> 
         <vm:ViewModelTemplateSelector InputTemplate="{StaticResource InLabel}" OutputTemplate="{StaticResource OutLabel}"/> 
        </GridViewColumn.CellTemplateSelector> 
       </GridViewColumn> 
       <GridViewColumn Header="Value"> 
        <GridViewColumn.CellTemplateSelector> 
         <vm:ViewModelTemplateSelector InputTemplate="{StaticResource InValue}" OutputTemplate="{StaticResource OutValue}"/> 
        </GridViewColumn.CellTemplateSelector> 
       </GridViewColumn> 
      </GridView> 
     </ListView.View> 
    </ListView> 

或者,如果您想將它全部保留在XAML中,則可以依賴DataType來爲您解析正確的模板。通常情況下,您只需將它們放入最接近容器的Resources集合中,但不幸的是,GridViewColumn不是UI元素,因此沒有Resources集合。您可以通過在ContentControl中增加了對能容納自己的類型模板每個單元解決這個問題:

<ListView ItemsSource="{Binding GenericObservableCollection}"> 
     <ListView.View> 
      <GridView> 
       <GridViewColumn Header="Type"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <ContentControl Content="{Binding}"> 
           <ContentControl.Resources> 
            <DataTemplate DataType="{x:Type vm:ActionInputViewModel}"> 
             <TextBlock Text="Input"/> 
            </DataTemplate> 
            <DataTemplate DataType="{x:Type vm:ActionOutputViewModel}"> 
             <TextBlock Text="Output"/> 
            </DataTemplate> 
           </ContentControl.Resources> 
          </ContentControl> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn Header="Value"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <ContentControl Content="{Binding}"> 
           <ContentControl.Resources> 
            <DataTemplate DataType="{x:Type vm:ActionInputViewModel}"> 
             <TextBlock Text="{Binding Property1}"/> 
            </DataTemplate> 
            <DataTemplate DataType="{x:Type vm:ActionOutputViewModel}"> 
             <TextBlock Text="{Binding Property2}"/> 
            </DataTemplate> 
           </ContentControl.Resources> 
          </ContentControl> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
      </GridView> 
     </ListView.View> 
    </ListView> 

無論哪種方式,應該給你同樣的結果。

+0

完美。感謝您爲我所考慮的兩種方法提供詳細的答案。 – scuba88

+0

嘖嘖,幾天後,我真的很緊張,但你釘了它。我的錯誤是我正在綁定ContentControl的'DataContext',而不是正確指出的'Content'。榮譽和感謝。 –

+0

我喜歡它,當人們真正花時間在他們的答案。你提供的細節很明顯。不錯的工作。 +1。 – cplotts

相關問題