2013-02-01 32 views
13

複数のタイプのビューモデルを含むObservableCollectionがあり、それぞれのGridViewColumnのCellTemplates内の各タイプごとにDataTemplateを作成したいと思います。この単純な例では、ベースViewModelを作成できましたが、xamlからこれを行うことができます。以下のxamlは、私がやろうとしていることを示しています。ここでは、DataTemplateの1つが各CellTemplateに使用されます。GridViewColumnの各DataTypeのDataTemplate CellTemplate

GridViewColumn.Resourcesがある場合は、DataTemplatesを定義して、そこにDataTemplateとCellTemplateのContentPresenterを使用しますが、私はそれを行うことはできません。私は、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 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に保存したい場合は、DataTypesを使用して適切なテンプレートを解決することができます。通常は、それらを最も近いコンテナのResourcesコレクションに入れるだけですが、残念ながらGridViewColumnはUI要素ではないため、Resourcesコレクションはありません。

<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

さて、私は何時間も揺れるのだが、あなたはそれを釘付けにした。私のエラーは、あなたが正しく指摘したように、 'Content'とは対照的に' ContentControl'の 'DataContext'をバインドしていたことでした。賞賛と感謝。 –

+0

私は人々が実際に彼らの答えに時間を費やすときにそれを愛する。あなたが提供した詳細は明らかです。良くやった。 +1。 – cplotts

関連する問題