it-roy-ru.com

Разница между стилем и ControlTemplate

Не могли бы вы сказать мне, в чем основные различия между Style и ControlTemplate? Когда или почему использовать один или другой?

На мой взгляд, они точно такие же такие же . Поскольку я начинающий, я думаю, что я не прав, поэтому мой вопрос.

51
Stephane Rolland

В стиле вы устанавливаете свойства элемента управления.

<Style x:Key="MyButtonStyle" TargetType="Button">
    <Setter Property="Background" Value="Red"/>
</Style>

<Button Style="{StaticResource MyButtonStyle}"/>

Для всех кнопок, использующих этот стиль, фон будет иметь красный цвет.

В шаблоне вы определяете UI (структуру) элемента управления.

<ControlTemplate x:Key="MyButtonTemplate" TargetType="Button">
    <Grid>
        <Rectangle Fill="Green"/>
        <ContentPresenter/>
    </Grid>
</ControlTemplate>

<Button Template="{StaticResource MyButtonTemplate}"/>

Все кнопки, которые используют этот шаблон, будут иметь зеленый фон, который нельзя изменить.

Значения, установленные в шаблоне , могут быть заменены только путем замены всего шаблона. Значения в style могут быть заменены путем явного задания значения при использовании элемента управления. Вот почему лучше использовать свойства элемента управления, используя TemplateBinding вместо значений кодирования.

<ControlTemplate x:Key="MyButtonTemplate" TargetType="Button">
    <Grid>
        <Rectangle Fill="{TemplateBinding Background}"/>
        <ContentPresenter/>
    </Grid>
</ControlTemplate>

Теперь шаблон использует значение свойства Background кнопки, к которой он применяется, поэтому его можно настроить:

<Button Template="{StaticResource MyButtonTemplate}" Background="Yellow"/>

Еще одна полезная функция - элементы управления могут выбирать стиль по умолчанию, не назначая им определенный стиль. Вы не можете сделать это с помощью шаблона.

Просто удалите атрибут стиля x: Key (опять же: вы не можете сделать это с помощью шаблонов). Все кнопки в визуальном дереве под стилем будут применены к этому стилю.

Объединение шаблонов и стилей является очень мощным: вы можете установить свойство Template в стиле:

<Style TargetType="Button">
    <Setter Property="Background" Value="Red"/>
    <Setter Property="Template">
        <Setter.Value>
             <ControlTemplate TargetType="Button">
                 <Grid>
                     <Rectangle Fill="{TemplateBinding Background"/>
                     <ContentPresenter/>
                 </Grid>
             </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
68
Erno de Weerd

Нет, действительно, вы совершенно не правы. Стили устанавливают свойства на элементах управления. ControlTemplate - это свойство используется большинством элементов управления, которые определяют способ их визуализации.

Чтобы уточнить, вы можете использовать стиль, чтобы сгруппировать настройки для набора свойств, чтобы вы могли использовать его повторно для стандартизации ваших элементов управления. Стили могут быть заданы явно на элементах управления или применены ко всему определенному типу.

Шаблоны элементов управления могут быть установлены стилем или заданы явно для элемента управления, чтобы изменить его внешний вид. Все элементы управления имеют шаблоны по умолчанию (и стили в этом отношении), которые встроены в сборки .net wpf. Это очень поучительно, когда я вижу это и понимаю, как разработчики wpf реализовали обычные версии всех элементов управления. Если у вас установлен Expression Blend, посмотрите в его папке «SystemThemes».

Обновление:

Чтобы понять, как Styles и ControlTemplates могут «добавлять элементы управления». Так или иначе, ControlTemplate - единственный способ определить элементы управления, из которых состоит элемент управления . Но некоторые стандартные элементы управления .net позволяют использовать элементы управления вместо текста. 

Например:

<GroupBox>
  <GroupBox.Header>
    <CheckBox/>
  </GroupBox.Header>
</GroupBox>

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

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

Независимо от того, устанавливаете ли вы свойства элемента управления (Content, Header, ControlTemplate, IsEnabled и т.д.) Напрямую или через стиль, значения не имеют, стили - это только удобство.

Надеюсь, это ответит на ваш вопрос более четко.

23
Andre Luus

Стиль можно рассматривать как удобный способ применить набор значений свойств к нескольким элементам. Вы можете изменить внешний вид по умолчанию, установив свойства, такие как FontSize и FontFamily, непосредственно для каждого элемента TextBlock. Однако, если вы хотите, чтобы ваши элементы TextBlock имели общие свойства, вы можете создать стиль в разделе «Ресурсы» вашего файла XAML.

С другой стороны, шаблон ControlTemplate определяет визуальную структуру и визуальное поведение элемента управления. Вы можете настроить внешний вид элемента управления, присвоив ему новый шаблон ControlTemplate. Когда вы создаете ControlTemplate, вы заменяете внешний вид существующего элемента управления без изменения его функциональности. Например, вы можете сделать кнопки в вашем приложении круглыми вместо квадратной формы по умолчанию, но кнопка все равно вызовет событие Click.

Ссылка: http://msdn.Microsoft.com/en-us/library/ms745683.aspx

13
Teoman Soygul

Я нашел некоторые интересные различия в Разница между стилями и шаблонами (MSDN)

Style: Вы можете установить только ранее существующие свойства в стиле. Например, вы не можете установить значение по умолчанию для свойства, которое принадлежит новой детали, добавленной в шаблон.

Template: Когда вы изменяете шаблон, вы получаете доступ к большему количеству частей элемента управления, чем при изменении стиля. Например, вы можете изменить способ отображения всплывающего списка в поле со списком или изменить вид кнопки, которая вызывает всплывающий список в поле со списком, изменив шаблон элементов.


Style: Вы можете использовать стили, чтобы указать поведение элемента управления по умолчанию. Например, в стиле кнопки вы можете указать триггер, чтобы при наведении курсора мыши на кнопку цвет фона изменялся. Эти изменения свойств происходят мгновенно (они не могут быть анимированы постепенно).

Template: Вы можете указать поведение любых новых и существующих частей в шаблоне с помощью триггеров. Например, вы можете указать триггер, чтобы, когда пользователь наводит указатель мыши на кнопку, цвет одной из частей изменялся. Эти изменения свойств могут быть мгновенными или анимированными постепенно для получения плавного перехода.

2
Bakri Bitar

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

Стиль является более гибким, чем ControlTemplate.

От Windows Presentation Foundation Unleashed , Адам Натан и банда (писатели) утверждают следующее:

  • «Помимо удобства комбинирования шаблона [со стилем с использованием установщика ControlTemplate стиля] с произвольными настройками свойств, существуют важные преимущества этого [установки установщика ControlTemplate на стиль]:

    1. Это дает вам эффект шаблонов по умолчанию. Например, когда типизированный стиль применяется к элементам по умолчанию, и этот стиль содержит настраиваемый шаблон элемента управления, шаблон элемента управления применяется без каких-либо явных отметок на этих элементах.
    2. Это позволяет вам предоставлять значение по умолчанию, но переопределяемое свойство, которое управляет внешним видом шаблона. Другими словами, он позволяет вам уважать свойства шаблонного родителя, но при этом предоставлять собственные значения по умолчанию. "

Другими словами, создание стиля позволяет пользователю установщика шаблона стиля переопределять набор значений, даже если они не использовали TemplateBinding (например, {TemplateBinding Width}). Если вы жестко закодировали Width в своем стиле, пользователь стиля все равно может переопределить его, но если вы жестко закодировали это свойство Width в шаблоне, пользователь застрянет с ним.

Кроме того, (и это немного сбивает с толку) при использовании ContentTemplate с TemplateBinding пользователь должен установить это свойство, иначе он будет использовать свойство по умолчанию для TargetType. Если вы используете стиль, вы можете переопределить свойство TargetType по умолчанию, используя для этого свойства установщик, а затем применив TemplateBinding, ссылающийся на этот установщик. Книга объясняет это лучше, стр. 338 (Смешивание шаблонов со стилями)

0
John C