Вопрос

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

Это было полезно?

Решение

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

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

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

Мои практические правила (не применимы в каждом случае, судите сами):

  1. Внутри ControlTemplate использовать ContentPresenter
  2. Вне ControlTemplate (включая DataTemplate и внешние шаблоны) постарайтесь не использовать ни один из них, если вам нужно, вы должны предпочесть ContentPresenter
  3. Подкласс ContentControl если вы создаете собственный «безобразный» элемент управления, в котором размещается контент, и вы не можете получить тот же результат, изменив существующий шаблон элемента управления (это должно быть крайне редко).

Другие советы

ContentPresenter обычно используется в ControlTemplate в качестве заполнителя, говорящего «поместите сюда фактическое содержимое».

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

Недавно я написал пост в своем блоге об этих двух элементах управления:

ContentPresenter vs ContentControl (РЕДАКТИРОВАТЬ:Неработающая ссылка заменена на архивированную версию.)

Тот Самый ContentPresenter.Источник контента это то, что на самом деле составляет самую большую разницу между этими двумя классами.Свойство ContentSource имеет смысл только в ControlTemplate;он определяет, с каким свойством TemplatedParent должно быть сопоставлено содержимое.Например, если элемент управления содержит свойство зависимости MyProperty1, тогда мы могли бы найти следующее в пределах его ControlTemplate:

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

Содержимое ContentPresenter получит значение MyProperty1.

Пожалуйста, обратите внимание, что если название объекта недвижимости Content, нет необходимости указывать ContentSource поскольку это значение по умолчанию.

Для тех, кто знает AngularJS:это похоже на преодоление меканизма.

Иногда пример проще, чем теоретический жаргон.На веб-сайте MS (прокрутите вниз: http://msdn.microsoft.com/en-us/library/system.windows.controls.contentpresenter(v=vs.110).aspx), в качестве примера используется кнопка.Кнопка имеет ContentControl, который позволяет вам разместить один элемент управления или пользовательский элемент управления, который может быть изображением, текстом, флажком, StackPanel, сеткой и т. д.

После настройки Button теперь в Xaml вы можете написать

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

В приведенном выше примере кода «my:Button.Content» — это ContentControl.AnotherControl будет помещен в то место, которое вы указали, где находится ContentPresenter.

Аналогично, при сравнении TextBox и TextBlock у TextBox есть ContentPresenter, в который вы можете вставлять что-то, как в приведенном выше примере с кнопкой, тогда как у TextBlock его нет.TextBlock позволяет вводить только текст.

Это старый вопрос, но я только что заканчивал разработку анимированного элемента управления плиткой, шаблона, основанного на универсальном приложении. Посмотрите на этот код из старого SDK Phone WP7/8:

<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 также можно использовать для отображения контента, но тогда он служит и контейнером, и презентатором.Таким образом, в приведенном выше примере кода его цель разделена на Контейнер и Презентер.В динамических примерах вы можете отобразить контейнер (он может иметь пустой фон или что-то еще, чего там еще нет), а затем динамически заполнить его содержимым презентатора.У контейнера есть размеры (ширина, высота и т. д.), вы помещаете эти свойства в элемент управления контейнера и представляете в нем содержимое.В примере ContentControl определяет, что нужно сделать с содержимым презентатора.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top