ContentControlとContentPresenterの違いは何ですか?


208

ContentPresenter代わりにContentControl(およびその逆)を使用するタイミングがわかりません。現時点では、ContentControlほとんど常にDataTemplates を使用しています。いつがContentPresenter良い選択でしょうか?なぜ?

回答:


163

ContentControl他の要素を含み、- Contentプロパティを持つコントロールの基本クラスです(たとえば、Button)。

ContentPresenter コンテンツを表示するためにコントロールテンプレート内で使用されます。

ContentControlを直接使用する場合(基本クラスとして使用することになっています)、ContentPresenterを使用してコンテンツを表示するコントロールテンプレートがあります。

私の経験則(すべての場合に当てはまるわけではありません、あなたの判断を使用してください):

  1. 内部ControlTemplate使用ContentPresenter
  2. 外部ControlTemplateDataTemplateテンプレートを含む、外部のテンプレート)のいずれも使用しないようにします。必要な場合は、優先する必要があります。ContentPresenter
  3. ContentControlコンテンツをホストするカスタムの「ルックレス」コントロールを作成していて、既存のコントロールのテンプレートを変更しても同じ結果を得ることができない場合は、サブクラス化します(これは非常にまれです)。

1
それは、一般的に、DataPresenter内でContentPresenterを使用する必要があることを意味します。次に、新しいコントロールを作成する場合は、ContentControlを基本クラスとして使用しますか?
Wilka、2009

ContentPresenterを使用する場合とContentControlを使用する場合の詳細を含めて、回答を編集しました
Nir

1
わかりましたContentPresenterをContentControlの代わりにテンプレートで使用するべきだと思いましたが、なぜですか
SLL

32
@sll-ContentControlは、「コンテンツ」(例:ラベル)を表示するすべてのコントロールの基本クラスです。ContentPresenterは、コンテンツを表示するためにContentControlによって内部的に使用されるコードです。つまり、1。ContentPresenterはより軽量です。コントロールテンプレートの内部および3 ContnetPresenterが(から継承)ContentControlには拡張するように設計されている間そのままで使用するように設計されて使用さ
ニール

23
ContentPresenterは、Contentプロパティを設定する場合、ContentControlとは異なる動作をします。ContentPresenterのContentプロパティを設定すると、そのDataContextはContentプロパティと一致するように変更されますが、ContentControlのDataContextは影響を受けません。ContentPresenterの他のプロパティがバインディングを介して設定されている場合、これは重要です。DataContextが変更されると、すべてのバインディングがそれをソースとして使用するためです。
user195275 14年

25

ContentPresenterは通常、「実際のコンテンツをここに置く」と言うプレースホルダーとして、ControlTemplateで使用されます。

ContentControlは、必ずしもテンプレート内ではなく、どこでも使用できます。割り当てられたコンテンツのタイプに定義されているDataTemplateを取得します


6
ContentPresenterによって、DataTemplateがそのコンテンツに適用されることもないのですか?それはその主な目的の1つではありませんか?
Drew Noakes、

1
うーん、たぶん。とにかく、Bea Stollnitzの説明は私のものよりもはるかに優れています;)
Thomas Levesque

あなたの簡潔な答えはそれをすぐに要約しているように見えました:ContentPresenterの全体のデザインは単にDataTemplateインフレーションを「実装する」ことだと思います---テンプレートを見つけてインフレートし、DataContextを設定するという唯一の仕事があるようです。そして、できるだけ「消える」ように試みます(膨張したテンプレート内で、ContentPresenterからのTextElementプロパティなどのアンビエントプロパティにバインドすることができます)。他のことを心配する必要はありません。テンプレートを比較的スリムに膨張させるだけです。(私は最もスリムなものを探しています!)
Steven Coco

9

私は最近、これら2つのコントロールについてブログに投稿しました。

ContentPresenterとContentControl(編集:リンク切れはアーカイブバージョンに置き換えられました。)

ContentPresenter.ContentSourceは、実際には、二つのクラスの最大の違いを作るものです。ContentSourceプロパティは、ControlTemplate内でのみ意味があります。コンテンツのマッピングに使用するTemplatedParentプロパティを決定します。たとえば、コントロールに依存関係プロパティが含まれている場合、MyProperty1その中に以下が見つかる可能性がありますControlTemplate

<ControlTemplate TargetType="MyControl" >
    [...]
       <ContentPresenter ContentSource="MyProperty1" />
    [...]
</ControlTemplate>

ContentPresenterのコンテンツはの値を受け取りますMyProperty1

プロパティの名前がの場合は、デフォルト値Contentなので指定する必要はありませんContentSource

angularJsを知っている人のために:これはメカニズムのトランクルードに似ています。


2

それは古い質問ですが、私はアニメーション化されたTile Control(ユニバーサルアプリ用のテンプレートに基づくテンプレート)の開発を終えたところです。古いPhone WP7 / 8 SDKの次のコードを見てください。

<ContentControl x:Name="contentControl" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch">
    <ContentPresenter x:Name="contentPresenter" CacheMode="BitmapCache"/>
</ContentControl>

ここでは、ContentControlがコンテンツを表示するためのコンテナおよびプレゼンターであることがわかります。ほとんどの場合、ControlTemplateはコンテナになりますが、ControlTemplate別のコンテナに追加する場合は、コンテナを追加ContentControlしてコンテンツを個別に表示できContentPresenterます。別のコンテナーが必要ない場合はControlTemplateControlPresentersコンテンツブロックを表示するために、少なくともMicrosoftの人がWP7 / 8 SDKを開発したときに行ったのと同じことです。ContentControlはコンテンツの表示にも使用できますが、コンテナーとプレゼンターの両方として機能します。上記のサンプルコードでは、その目的はコンテナとプレゼンターに分かれています。動的サンプルでは、​​コンテナーを表示し(空の背景またはまだ存在しないものがある可能性があります)、プレゼンターコンテンツを動的に入力できます。コンテナには寸法(幅、高さなど)があり、それらのプロパティをコンテナコントロールに配置してコンテンツを表示します。サンプルでは、​​ContentControlがプレゼンターコンテンツで実行する必要があることを決定します。


1

例は理論的な専門用語よりも簡単な場合があります。MS Webサイト(下部までスクロール:http : //msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter (v= vs.110).aspx ))では、ボタンを次のように使用します例。ButtonにはContentControlがあり、1つのコントロール、または画像、テキスト、チェックボックス、スタックパネル、グリッドなどのカスタムコントロールを配置できます。

Buttonのカスタマイズ後、Xamlで次のように書くことができます

<my:Button>
   <my:Button.Content>
      <my:AnotherControl>
   </my:Button.Content>
</my:Button>

上記のコード例では、「my:Button.Content」はContentControlです。AnotherControlは、ContentPresenterがある場所を指定した場所に配置されます。

同様に、TextBoxとTextBlockを比較すると、上記のButtonの例のように、TextBoxにはコンテンツプレゼンターがあり、TextBlockにはありません。TextBlockはテキストの入力のみを許可します。


2
AにButtonは[ ](msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol(v = vs.110).aspx)ありません。ContentControlこれ(継承)ContentControlです。にはButton ありContentPresenterます。これを標準のButtonで行うことができ、カスタマイズする必要がないことに注意してください。
またはMapper、2014年

しかし、それとは関係のない、この答えは、代わりのかと理由を説明しないContentPresenterContentControlでちょうど同様に使用することができなかったControlTemplateのコンテンツを表示しますButton。そのため、質問には答えません。
またはMapper、2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.