Ответы:
ContentControlявляется базовым классом для элементов управления, которые содержат другие элементы и имеют Content-property (например, Button).
ContentPresenter используется внутри шаблонов управления для отображения содержимого.
ContentControlпри непосредственном использовании (предполагается, что он будет использоваться в качестве базового класса), имеет шаблон элемента управления, который использует ContentPresenter для отображения своего содержимого.
Мои эмпирические правила (не применимы в каждом случае, используйте ваше мнение)
ControlTemplateиспользованияContentPresenterControlTemplate(включая DataTemplateи внешние шаблоны) старайтесь не использовать ни один из них, если вам нужно, вы должны предпочестьContentPresenterContentControlесли вы создаете пользовательский элемент управления «без внешнего вида», который содержит содержимое, и вы не можете получить тот же результат, изменяя шаблон существующего элемента управления (это должно быть крайне редко).ContentPresenter обычно используется в ControlTemplate как заполнитель, чтобы сказать «поместите фактический контент здесь».
ContentControl может использоваться где угодно, не обязательно в шаблоне. Он подберет любой DataTemplate, определенный для типа назначенного ему контента.
Недавно я написал в своем блоге сообщение об этих двух элементах управления:
ContentPresenter против ContentControl (EDIT: неработающая ссылка заменена на архивную версию.)
ContentPresenter.ContentSource является то , что на самом деле делает большое различие между этими двумя классами. Свойство ContentSource имеет смысл только в ControlTemplate; он определяет, с каким свойством TemplatedParent должно отображаться содержимое. Например, если элемент управления содержит свойство зависимости MyProperty1, то мы можем найти в нем следующее ControlTemplate:
<ControlTemplate TargetType="MyControl" >
[...]
<ContentPresenter ContentSource="MyProperty1" />
[...]
</ControlTemplate>
Контент ContentPresenter получит значение MyProperty1.
Обратите внимание: если имя свойства Contentуказано, указывать ContentSourceего не нужно, так как это значение по умолчанию.
Для тех, кто знает angularJs: это похоже на включение механизма.
Это старый вопрос, но я только заканчивал разработку анимированного 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. Если вам не нужен отдельный контейнер, просто используйте ControlTemplateиControlPresentersдля отображения блоков контента, по крайней мере, так поступили ребята из Microsoft, когда разрабатывали WP7 / 8 SDK. ContentControl также можно использовать для отображения контента, но затем он служит как контейнером, так и презентатором. Таким образом, в приведенном выше примере кода его назначение разделено на Контейнер и Presenter. В динамических примерах вы можете отобразить контейнер (он может иметь пустой фон или что-то, чего еще нет), а затем динамически заполнить его содержимым презентатора. Контейнер имеет размеры (ширину, высоту и т. Д.), Вы помещаете эти свойства в элемент управления контейнера и представляете содержимое на нем. В примере ContentControl определяет, что должно быть сделано с содержимым презентатора.
Иногда пример проще, чем теоретический жаргон. На веб-сайте MS (прокрутите вниз: http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter(v=vs.110).aspx ) она использует кнопку как пример. Кнопка имеет ContentControl, который позволяет вам разместить один элемент управления или пользовательский элемент управления, который может быть изображением, текстом, CheckBox, StackPanel, Grid и т. Д.
После настройки кнопки, теперь на Xaml, вы можете написать
<my:Button>
<my:Button.Content>
<my:AnotherControl>
</my:Button.Content>
</my:Button>
В приведенном выше примере кода «my: Button.Content» является ContentControl. AnotherControl будет местом для того, что вы указали, где находится ContentPresenter.
Точно так же, когда сравниваются TextBox и TextBlock, TextBox имеет ContentPresenter, чтобы вы могли что-то добавить в него, как в приведенном выше примере Button, тогда как TextBlock - нет. TextBlock позволяет только вводить текст.
ButtonНе имеет в [ ContentControl] (msdn.microsoft.com/en-us/library/system.windows.controls.contentcontrol (v = vs.110) .aspx), он является (наследует от) ContentControl. Button ИмеетContentPresenter . Обратите внимание, что вы можете сделать это со стандартом Button, не нужно настраивать его.
ContentPresentera ContentControlне использоваться так же хорошо в ControlTemplateотображении содержания Button. Как таковой, он не отвечает на вопрос.