Разница между стилем и ControlTemplate - PullRequest
57 голосов
/ 26 мая 2011

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

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

Ответы [ 5 ]

71 голосов
/ 26 мая 2011

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

<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}"/>

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

Значения, установленные в шаблоне , могут быть заменены только путем замены всего шаблона. Значения в стиле могут быть заменены путем явного задания значения при использовании элемента управления. Вот почему лучше использовать свойства элемента управления, используя 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>
23 голосов
/ 26 мая 2011

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

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

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

UPDATE:

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

Например:

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

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

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

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

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

14 голосов
/ 26 мая 2011

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

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

Ref: http://msdn.microsoft.com/en-us/library/ms745683.aspx

2 голосов
/ 06 февраля 2015

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

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

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


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

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

0 голосов
/ 05 февраля 2014

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

Стиль более гибкий, чем ControlTemplate.

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...