2009-08-17 17 views

Respuesta

142

ContentControl es una clase base para los controles que contienen otros elementos y tienen un -property Content (por ejemplo, Button).

ContentPresenter se usa dentro de plantillas de control para mostrar contenido.

ContentControl, cuando se usa directamente (se supone que debe usarse como una clase base), tiene una plantilla de control que usa ContentPresenter para mostrar su contenido.

EDIT: Mis reglas de oro (no aplicable en todos los casos, utilice su juicio):

  1. Dentro ControlTemplate uso ContentPresenter
  2. Fuera de ControlTemplate (incluyendo DataTemplate y las plantillas externas) Trate de no usar cualquier de ellos, si es necesario, debe preferir ContentPresenter
  3. Subclase ContentControl si está creando un control "sin aspecto" personalizado que aloje contenido y no puede obtener el mismo resultado cambiando la plantilla de un control existente (que debería ser extremadamente raro).
+1

¿Eso significa que, en general, probablemente debería usar ContentPresenter dentro de mis plantillas de datos, porque es más liviano (pero funcionalmente equivalente cuando se usa en una plantilla de datos como esta)? ¿Entonces solo uso ContentControl como clase base si estoy escribiendo un nuevo control? – Wilka

+0

He editado la respuesta con más detalles cuando usaría ContentPresenter y cuándo ContentControl – Nir

+1

Ok, tengo una idea de que ContentPresenter debería usarse en plantillas en lugar de ContentControl, pero ¿por qué? – sll

20

ContentPresenter se utiliza generalmente en ControlTemplate, como marcador de posición para decir "poner aquí el contenido real".

Un ContentControl se puede usar en cualquier lugar, no necesariamente en una plantilla. Se recogerá cualquier DataTemplate definido para el tipo de contenido asignado a él

+6

¿No sería un ContentPresenter también causar que se aplicara un DataTemplate a su contenido? ¿No es ese uno de sus propósitos principales? –

+1

mmm ... sí, probablemente. De todos modos, la explicación de Bea Stollnitz es mucho mejor que la mía;) –

8

Recientemente he escrito una entrada en mi blog con respecto a estos dos controles:

ContentPresenter vs ContentControl (EDIT:. Conexión quebrada sustituido con versión archivada)

El ContentPresenter.ContentSource es lo que realmente hace que la la mayor diferencia entre las dos clases. La propiedad ContentSource solo tiene sentido dentro de ControlTemplate; determina con qué propiedad de TemplatedParent debe correlacionarse el contenido. Por ejemplo, si un control contiene una propiedad de dependencia MyProperty1, entonces podemos encontrar la siguiente dentro de su ControlTemplate:

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

El contenido de la ContentPresenter recibirá el valor de MyProperty1.

Tenga en cuenta que si el nombre de la propiedad es Content, no es necesario especificar ContentSource ya que es el valor predeterminado.

Para aquellos que conocen angularJs: esto es similar al mecanismo de transclude.

0

A veces un ejemplo es más fácil que la jerga teórica. En un sitio web de MS (Desplácese hasta la parte inferior: http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter(v=vs.110).aspx), utiliza un botón como ejemplo.Un botón tiene un control de contenido, que le permite colocar un control o un control personalizado que podría ser una imagen, texto, casilla de verificación, panel de pila, cuadrícula, lo que sea.

Después de la personalización del botón, ahora en el XAML, puede escribir

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

En el código de ejemplo anterior, el "mi: Button.Content" es el ContentControl. El AnotherControl se colocará según lo que usted especificó donde está el ContentPresenter.

De forma similar, cuando se compara TextBox y TextBlock, TextBox tiene un ContentPresenter para que puedas meter cosas en él igual que el ejemplo de Button anterior, mientras que TextBlock no lo hace. Un TextBlock solo le permite ingresar texto.

+1

A ['Button'] (http://msdn.microsoft.com/en-us/library/system.windows.controls.button%28v=vs.110%29.aspx) no * tiene * a [' ContentControl'] (msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol (v = vs.110) .aspx), it * es un * (hereda de) 'ContentControl'. El 'Botón' * tiene * a [' ContentPresenter'] (http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter%28v=vs.110%29.aspx). Tenga en cuenta que puede hacer eso con el 'Botón' estándar, sin necesidad de personalizarlo. –

+0

Pero sin relación con eso, esta respuesta no explica si, y por qué, en lugar del 'ContentPresenter', un' ContentControl' no se podría usar igual de bien en 'ControlTemplate' para mostrar el contenido del' Botón'. Como tal, no responde la pregunta. –

0

Su una vieja pregunta, pero yo estaba terminando el desarrollo de un control del azulejo de animación, plantilla basada en una aplicación universal, mira el código del viejo teléfono WP7/8 SDK:

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

Aquí se puede ver ContentControl es el contenedor y el presentador para mostrar contenido. En la mayoría de los casos, el ControlTemplate será el Contenedor pero si desea en su ControlTemplate otro contenedor, puede colocar un Contenedor adicional: ContentControl en él y para presentar el contenido por separado ContentPresenter. Si no necesita un contenedor por separado, simplemente use ControlTemplate y ControlPresenters para mostrar bloques de contenido, al menos eso es lo que hicieron los chicos de Microsoft cuando desarrollaron el WP7/8 SDK. ContentControl también se puede usar para mostrar contenido pero luego sirve como contenedor y presentador. Por lo tanto, en el código de ejemplo anterior, su propósito se divide en Container y Presenter. En las muestras dinámicas, puede visualizar el contenedor (puede tener un fondo vacío o algo que aún no está allí) y luego llenarlo dinámicamente con el contenido del presentador. Un contenedor tiene dimensiones (ancho, alto, etc.), coloca esas propiedades en el control del contenedor y presenta contenido en él. En la muestra, ContentControl determina qué se debe hacer con el contenido del presentador.

Cuestiones relacionadas