В чем разница между ContentControl и ContentPresenter?


Я не уверен, когда я должен использовать ContentPresenter вместо ContentControl (и наоборот). На данный момент я использую ContentControl почти все время в моей DataTemplate s. Когда бы ContentPresenter быть лучшим выбором? и почему?

5 189

5 ответов:

ContentControl является базовым классом для элементов управления, которые содержат другие элементы и Content-имущества (например, Button).

ContentPresenter используется внутри шаблонов управления для отображения содержимого.

ContentControl, при непосредственном использовании (он должен использоваться в качестве базового класса), имеет шаблон элемента управления, который использует ContentPresenter для отображения его содержимого.

мои эмпирические правила (не применимо в каждом случае, используйте свой суждение):

  1. внутри ControlTemplate использовать ContentPresenter
  2. за пределами ControlTemplate (включая DataTemplate и внешние шаблоны) старайтесь не использовать ни один из них, если вам нужно, вы должны предпочесть ContentPresenter
  3. подкласс 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 определяет, что должно быть сделано с содержимым презентатора.