В чем разница между ContentControl и ContentPresenter?
Я не уверен, когда я должен использовать ContentPresenter
вместо ContentControl
(и наоборот). На данный момент я использую ContentControl
почти все время в моей DataTemplate
s. Когда бы ContentPresenter
быть лучшим выбором? и почему?
5 ответов:
ContentControl
является базовым классом для элементов управления, которые содержат другие элементы иContent
-имущества (например,Button
).
ContentPresenter
используется внутри шаблонов управления для отображения содержимого.
ContentControl
, при непосредственном использовании (он должен использоваться в качестве базового класса), имеет шаблон элемента управления, который использует ContentPresenter для отображения его содержимого.мои эмпирические правила (не применимо в каждом случае, используйте свой суждение):
- внутри
ControlTemplate
использоватьContentPresenter
- за пределами
ControlTemplate
(включаяDataTemplate
и внешние шаблоны) старайтесь не использовать ни один из них, если вам нужно, вы должны предпочестьContentPresenter
- подкласс
ContentControl
Если вы создаете пользовательский элемент управления "lookless", который содержит содержимое, и вы не можете получить тот же результат, изменив шаблон существующего элемента управления (это должно быть крайне редко).
ContentPresenter обычно используется в ControlTemplate, как заполнитель, чтобы сказать "поместите фактическое содержимое здесь".
ContentControl можно использовать в любом месте, не обязательно в шаблоне. Он подберет любой DataTemplate, определенный для типа контента, назначенного ему
недавно я написал сообщение в своем блоге об этих двух элементах управления:
ContentPresenter vs ContentControl (EDIT: сломанная ссылка заменена архивной версией.)
The ContentPresenter.ContentSource что на самом деле делает большое различие между двумя классами. Свойство ContentSource имеет смысл только в пределах ControlTemplate; оно определяет, с каким свойством TemplatedParent должно быть сопоставлено содержимое. Например, если элемент управления содержит свойство зависимостей
MyProperty1
, то мы могли бы найти следующее в егоControlTemplate
:<ControlTemplate TargetType="MyControl" > [...] <ContentPresenter ContentSource="MyProperty1" /> [...] </ControlTemplate>
содержимое ContentPresenter получит значение
MyProperty1
.обратите внимание, что если имя свойства
Content
, нет необходимости указыватьContentSource
как это значение по умолчанию.для тех, кто знает angularJs: это похоже на transclude mecanism.
иногда пример проще, чем теоретический жаргон. На веб-сайте MS (прокрутите вниз: http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter(v=vs.110).aspx), он использует кнопку в качестве примера. Кнопка имеет ContentControl, который позволяет разместить один элемент управления или пользовательский элемент управления, который может быть изображение, текст, флажок, StackPanel, сетка, что угодно.
после настройки кнопки, теперь на Xaml, вы можете пиши
<my:Button> <my:Button.Content> <my:AnotherControl> </my:Button.Content> </my:Button>
в приведенном выше примере кода, кнопка " my:.Content " - это ContentControl. AnotherControl будет местом для того, что вы указали, где находится ContentPresenter.
аналогично, при сравнении TextBox и TextBlock, TextBox имеет ContentPresenter для вас, чтобы наполнить вещи в нем так же, как в приведенном выше примере кнопки, тогда как TextBlock этого не делает. TextBlock позволяет только вводить текст.
его старый вопрос, но я только что закончил разработку анимированного элемента управления плитки, шаблон на основе универсального приложения, посмотрите на этот код из старого телефона 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 также может использоваться для отображения содержимого, но затем он служит как контейнером, так и презентатором. Поэтому в примере кода выше его назначение разбивается на контейнер и презентатор. В динамических образцах вы можете отобразить контейнер (он может иметь пустой фон или что-то, чего там нет yet), а затем динамически заполнить его содержимым презентатора. Контейнер имеет размеры (ширина,высота и т. д.), вы помещаете эти свойства в элемент управления контейнером и представляете на нем содержимое. В Примере ContentControl определяет, что должно быть сделано с содержимым презентатора.