web-dev-qa-db-ja.com

WPFでデータテンプレートの継承を使用する方法はありますか?

DataTemplate構成または継承(スタイルの "BasedOn"と同様)を持つことは可能ですか?それが必要な場合が2つあります。

  1. 継承されたクラスの場合:いくつかの継承されたクラスを持つ基本クラスがあります。派生クラスのDataTemplateごとに基本クラステンプレートを複製したくありません。

  2. 異なるビュー:同じクラスに対して、データテンプレートを定義し、必要に応じてそのテンプレートに追加します。例基本テンプレートはオブジェクトのデータを表示し、データを表示しながら(基本テンプレートを継承)、オブジェクトに対してさまざまなアクションを実行できるさまざまなテンプレートが必要です。

50
Fragilerus

この種のことをするために私が見つけた唯一のことはこれです:

<DataTemplate x:Key="BaseClass">
  <!-- base class template here -->
</DataTemplate>
<DataTemplate DataType="{x:Type app:BaseClass}">
  <ContentPresenter Content="{Binding}" 
                    ContentTemplate="{StaticResource BaseClass}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type app:DerivedClass}">
  <StackPanel>
    <ContentPresenter Content="{Binding}" 
                      ContentTemplate="{StaticResource BaseClass}"/>
    <!-- derived class extra template here -->
  </StackPanel>
</DataTemplate>

基本的に、これはキー(この場合はBaseClass)を使用して参照できる「共通」テンプレートを作成します。次に、基本クラスと派生クラスの実際のDataTemplateを定義します。派生クラステンプレートは、独自の「もの」を追加します。

msdn についてこれについていくつかの議論がありましたが、誰も私が見たより良い解決策を考え出しませんでした。

43
Liz

@Fragilerusと@Liz、実際にはもっと良いものを思いついたと思います。共有コンテンツはコンパイル時に設定される直接コンテンツであるため、追加のContentPresenterバインディングを回避するだけでなく、テンプレート内にテンプレートを適用する必要もない別のアプローチを次に示します。実行時に発生するのは、直接コンテンツ内で設定したバインディングのみです。そのため、他のソリューションと比較すると、UIが大幅に高速化されます。

<!-- Content for the template (note: not a template itself) -->
<Border x:Shared="False" 
        x:Key="Foo" 
        BorderBrush="Red" 
        BorderThickness="1" 
        CornerRadius="4">
    <TextBlock Text="{Binding SomeProp}" />
</Border>

<DataTemplate x:Key="TemplateA">
    <!-- Static resource - No binding needed -->
    <ContentPresenter Content="{StaticResource Foo}" /> 
</DataTemplate>

<DataTemplate x:Key="TemplateB">
    <!-- Static resource - No binding needed -->
    <ContentPresenter Content="{StaticResource Foo}" />
</DataTemplate>

重要:必ずx:Shared共有コンテンツの属性またはこれは機能しません。

WPF'y Way

上記のように、これはあなたが望んでいることを行うための最もWPFフレンドリーな方法ではありません。これは、まさにそれを行うDataTemplateSelectorクラスを使用して達成できます... selectは、設定した基準に基づいたデータテンプレートです。

たとえば、既知のデータタイプを検索して両方に同じDataTemplateを返すものを簡単に設定できますが、他のすべてのタイプでは、システムにフォールバックしてDataTemplateを解決します。それが実際にここで行うことです。

お役に立てれば! :)

22
MarqueIV