Respostas:
ContentControl
é uma classe base para controles que contêm outros elementos e têm uma Content
propriedade-(por exemplo, Button
).
ContentPresenter
é usado dentro dos modelos de controle para exibir o conteúdo.
ContentControl
, quando usado diretamente (deveria ser usado como uma classe base), possui um modelo de controle que usa o ContentPresenter para exibir seu conteúdo.
Minhas regras de ouro (não aplicável em todos os casos, use seu julgamento):
ControlTemplate
Uso internoContentPresenter
ControlTemplate
(incluindo DataTemplate
e fora de modelos) tente não usar nenhum deles, se necessário, você deve preferirContentPresenter
ContentControl
se você estiver criando um controle "sem aparência" personalizado que hospeda o conteúdo e não pode obter o mesmo resultado alterando o modelo de um controle existente (isso deve ser extremamente raro).O ContentPresenter geralmente é usado em um ControlTemplate, como um espaço reservado para dizer "coloque o conteúdo real aqui".
Um ContentControl pode ser usado em qualquer lugar, não necessariamente em um modelo. Ele selecionará qualquer DataTemplate definido para o tipo de conteúdo atribuído a ele
Recentemente, escrevi um post no meu blog sobre esses dois controles:
ContentPresenter vs ContentControl (EDIT: Link quebrado substituído pela versão arquivada.)
O ContentPresenter.ContentSource é o que realmente faz a maior diferença entre as duas classes. A propriedade ContentSource faz sentido apenas dentro de um ControlTemplate; determina com qual propriedade TemplatedParent o conteúdo deve ser mapeado. Por exemplo, se um controle contiver uma propriedade de dependência MyProperty1
, poderemos encontrar o seguinte dentro dele ControlTemplate
:
<ControlTemplate TargetType="MyControl" >
[...]
<ContentPresenter ContentSource="MyProperty1" />
[...]
</ControlTemplate>
O conteúdo do ContentPresenter receberá o valor de MyProperty1
.
Observe que, se o nome da propriedade for Content
, não há necessidade de especificar ContentSource
, pois é o valor padrão.
Para quem conhece Js angulares: isso é semelhante a transcluir o mecanismo.
É uma pergunta antiga, mas eu estava terminando o desenvolvimento de um controle de bloco animado, modelo baseado em um aplicativo universal, veja este código do antigo telefone WP7 / 8 SDK:
<ContentControl x:Name="contentControl" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch">
<ContentPresenter x:Name="contentPresenter" CacheMode="BitmapCache"/>
</ContentControl>
Aqui você pode ver que o ContentControl é o Container e o Presenter para exibir o conteúdo. Na maioria dos casos, o ControlTemplate será o Container, mas se você quiser em ControlTemplate
outro container, poderá colocar um Container extra: ContentControl
nele e para apresentar o conteúdo em separadoContentPresenter
. Se você não precisar de um contêiner separado, use ControlTemplate
eControlPresenters
para exibir blocos de conteúdo, pelo menos foi o que os funcionários da Microsoft fizeram quando desenvolveram o WP7 / 8 SDK. O ContentControl também pode ser usado para exibir conteúdo, mas serve como contêiner e apresentador. Portanto, no código de exemplo acima, seu objetivo é dividido em Container e Presenter. Em amostras dinâmicas, você pode exibir o contêiner (ele pode ter um plano de fundo vazio ou algo que ainda não existe) e preenchê-lo dinamicamente com o conteúdo do apresentador. Um contêiner possui dimensões (largura, altura etc.), você coloca essas propriedades no controle do contêiner e apresenta o conteúdo nele. Na amostra, o ContentControl determina o que deve ser feito com o conteúdo do apresentador.
Às vezes, um exemplo é mais fácil que o jargão teórico. Em um site da Microsoft (role para a parte inferior: http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter(v=vs.110).aspx ), ele usa um botão como um exemplo. Um botão possui um ContentControl, que permite colocar um controle ou um controle personalizado que pode ser uma imagem, texto, caixa de seleção, StackPanel, grade, qualquer que seja.
Após a personalização do Button, agora no Xaml, você pode escrever
<my:Button>
<my:Button.Content>
<my:AnotherControl>
</my:Button.Content>
</my:Button>
No código de exemplo acima, o "meu: Button.Content" é o ContentControl. O AnotherControl será o local que você especificou onde está o ContentPresenter.
Da mesma forma, quando se compara o TextBox e o TextBlock, o TextBox possui um ContentPresenter para você colocar coisas como o exemplo do botão acima, enquanto o TextBlock não. Um TextBlock permite apenas inserir texto.
Button
não possui um [ ContentControl
] (msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol (v = vs.110) .aspx), é um (herda de) ContentControl
. O Button
tem um ContentPresenter
. Observe que você pode fazer isso com o padrão Button
, sem necessidade de personalizá-lo.
ContentPresenter
, a ContentControl
não poderia ser usado tão bem na ControlTemplate
exibição do conteúdo do Button
. Como tal, não responde à pergunta.