.net wpf contentcontrol contentpresenter

.net - ¿Cuál es la diferencia entre ContentControl y ContentPresenter?



wpf (5)

No estoy seguro de cuándo debería usar ContentPresenter lugar de ContentControl (y viceversa). En este momento, estoy usando ContentControl casi todo el tiempo en mis DataTemplate . ¿Cuándo sería ContentPresenter una mejor opción? ¿y por qué?


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 ), usa un botón como un ejemplo. Un botón tiene un ContentControl, que le permite colocar un control o un control personalizado que puede ser una imagen, texto, CheckBox, StackPanel, Grid, lo que sea.

Después de la personalización de Button, ahora en el Xaml, puedes escribir

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

En el código de ejemplo anterior, el "my: Button.Content" es el ContentControl. El AnotherControl se ubicará según lo que haya especificado donde se encuentra el ContentPresenter.

De manera similar, cuando se comparan TextBox y TextBlock, TextBox tiene un ContentPresenter para que rellenes cosas como el ejemplo anterior del Botón, mientras que un TextBlock no lo hace. Un TextBlock solo te permite ingresar texto.


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

Un ContentControl se puede utilizar en cualquier lugar, no necesariamente en una plantilla. Recogerá cualquier DataTemplate definida para el tipo de contenido asignado a ella


Es una pregunta antigua, pero estaba terminando de desarrollar una plantilla animada de control de mosaico, basada en una aplicación universal, mira este código del antiguo 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í puede ver que el ContentControl es el contenedor y el presentador para mostrar contenido. En la mayoría de los casos, ControlTemplate será el Contenedor, pero si desea en su ControlTemplate otro contenedor, puede poner un Contenedor adicional: ContentControl en él y para presentar el contenido en un ContentPresenter separado. Si no necesita un contenedor separado, simplemente use ControlTemplate y ControlPresenters para mostrar los bloques de contenido, al menos eso es lo que hicieron los chicos de Microsoft cuando desarrollaron el WP7 / 8 SDK. El ContentControl también se puede usar para mostrar contenido, pero luego sirve como contenedor y presentador. Entonces, en el código de ejemplo anterior, su propósito se divide en Contenedor y Presentador. En las muestras dinámicas, podría mostrar el contenedor (puede tener un fondo vacío o algo que todavía no está allí) y luego rellenarlo dinámicamente con el contenido del presentador. Un contenedor tiene dimensiones (ancho, alto, etc.), usted pone esas propiedades en el control de contenedor y presenta contenido en él. En la muestra, el ContentControl determina qué se debe hacer con el contenido del presentador.


Recientemente escribí una publicación en mi blog sobre estos dos controles:

ContentPresenter vs ContentControl (EDIT: enlace roto reemplazado con la versión archivada).

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

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

El contenido de 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 saben angulares: esto es similar al mecanismo de transclusión.


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

ContentPresenter se utiliza dentro de las plantillas de control para mostrar contenido.

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

Mis reglas generales (no se aplican en todos los casos, utilice su criterio):

  1. Dentro de ControlTemplate use ContentPresenter
  2. Fuera de ControlTemplate (incluyendo DataTemplate y plantillas externas) intente no usar ninguno de ellos, si es necesario, debe preferir ContentPresenter
  3. Subclase ContentControl si está creando un control "sin aspecto" personalizado en el contenido del host y no puede obtener el mismo resultado al cambiar la plantilla de un control existente (que debería ser extremadamente raro).