Главная » WPF » Введение  в стили

0

Стиль  состоит  из трех компонентов:  установщиков свойств,  триггеров  и ре сурсов. Мы начнем с простой кнопки, у которой есть локальное  свойство, позво ляющее сделать фон красным:

<Button Background=’Red’> Hello, Red World!

</Button>

Попробуем перенести это свойство в стиль. При создании нового стиля мы должны сообщить (с помощью свойства  TargetType), к объектам какого типа он будет применяться:

<Style TargetType=’{x:Type Button}’>

</Style>

Чтобы  сделать  фон  красным,  нужно  определить  установщик свойства  с по мощью объекта Setter.  Установщики бывают двух типов: для свойств и для собы тий. Установщики свойств  позволяют  задать значение  свойства  для всех объек тов, с которыми  ассоциирован данный  стиль. Установщики событий  связывают обработчик событий с объектами, к которым применяется стиль. В общем случае для ассоциирования поведения  с элементами управления лучше пользоваться командами,  поэтому установщики событий встречаются  редко.

Имя свойства относится к целевому типу, определенному в стиле; таким обра

зом, имя «Background» означает Button.BackgroundProperty:

<Style TargetType=’{x:Type Button}’>

<Setter Property=’Background’ Value=’Red’ />

</Style>

При проектировании модели стилей  мы много спорили  о том, нужно ли раз рабатывать  особый синтаксис  для работы с установщиками свойств  и событий. Была  идея  ввести  такой  же синтаксис,  как «в момент  использования», то есть нечто такое:

<Style>

<!— не работает! —>

<Button Background=’Red’ />

</Style>

Напомним,  что один из постулатов  WPF гласит: разметка и объектная модель должны быть максимально похожи. В данном случае стандартные  правила инте рпретации  разметки  означали  бы, что нужно создать новую кнопку и задать для нее красный  фон. Но очевидно, что от стиля мы ожидаем совсем не этого. По су ществу, стиль – это сценарий настройки.  Он позволяет  настраивать свойства, со бытия, триггеры и ресурсы для объекта.

Применяя в стилях синтаксис установщиков, мы ясно говорим в разметке, что это именно сценарий настройки и сохраняем полную синхронизацию с объектной моделью. Чтобы ассоциировать стиль с типом, нужно установить  свойство Style:

<Button>

<Button.Style>

<Style TargetType=’{x:Type Button}’>

<Setter Property=’Background’ Value=’Red’ />

</Style>

</Button.Style>

Hello, Red World!

</Button>

В главе 6 мы видели, что можно воспользоваться ссылкой на ресурс для обоб

ществления определения стиля:

<Window …>

<Window.Resources>

<Style x:Key=’myStyle’ TargetType=’{x:Type Button}’>

<Setter Property=’Background’ Value=’Red’ />

</Style>

</Window.Resources>

<StackPanel>

<Button Style=’{DynamicResource myStyle}’> Hello, Red World!

</Button>

<Button Style=’{DynamicResource myStyle}’> Another button!

</Button>

</StackPanel>

</Window>

В главе 6 мы видели, как можно ассоциировать шаблоны данных с типом, вос пользовавшись свойством  DataTemplateKey вместо  прямой  ссылки  на шаблон. То же самое справедливо в отношении  стилей, нужно лишь в качестве ключа ука зать тип объекта, с которым ассоциируется стиль. Таким образом, мы сможем ав томатически применить  стиль ко всем объектам указанного  типа. Если в нашем примере  положить  ключ равным {x:TypeButton},  то любая кнопка, находящаяся внутри окна, будет красной:

<Window …>

<Window.Resources>

<Style x:Key=’{x:Type Button}’ TargetType=’{x:Type Button}’>

<Setter Property=’Background’ Value=’Red’ />

</Style>

</Window.Resources>

<Button>

Hello, Red World!

</Button>

</Window>

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

1  Может оказаться даже еще более запутанно: если не задать ключ стиля для поиска в словаре ресурсов, то автоматически используется целевой тип. Я такой трюк не рекомендую, так как читать разметку при этом становится сложнее.

Помимо установщиков, мы можем ассоциировать со стилем триггеры и ресур сы. Триггеры  работают точно так же, как для шаблонов элементов  управления и данных. Изменить цвет фона кнопки можно, присоединив триггер к свойству IsMouseOver:

<Style x:Key=’{x:Type Button}’ TargetType=’{x:Type Button}’>

<Setter Property=’Background’ Value=’Red’ />

<Style.Triggers>

<Trigger Property=’IsMouseOver’ Value=’True’>

<Setter Property=’Background’ Value=’Blue’ />

</Trigger>

</Style.Triggers>

</Style>

Возможно, у вас возник вопрос, в чем разница между ControlTemplate.Triggers и Style.Triggers? Напомним, что шаблон элемента управления оказывает влияние на дерево отображения элемента. Когда мы меняем цвет фона кнопки, создается впечатление, что стиль тоже воздействует на дерево отображения, но на самом де ле просто устанавливается свойство кнопки Background, а принятый по умолча нию шаблон в классе Button привязывает это свойство к элементу в дереве отоб ражения. Чтобы понять, в чем различие,  добавим еще один триггер для свойства IsPressed:

<Style x:Key=’{x:Type Button}’ TargetType=’{x:Type Button}’>

<Setter Property=’Background’ Value=’Red’ />

<Style.Triggers>

<Trigger Property=’IsMouseOver’ Value=’True’>

<Setter Property=’Background’ Value=’Blue’ />

</Trigger>

<Trigger Property=’IsPressed’ Value=’True’>

<Setter Property=’Background’ Value=’Yellow’ />

</Trigger>

</Style.Triggers>

</Style>

Запустив  эту  программу,  мы  обнаружим,   что  при  наведении   мыши  на кнопку, она не становится желтой. Причина в том, что шаблон Button по умолчанию  не привязывает свойство  Background ни к какому элементу  в де реве отображения в случае, когда кнопка нажата. Чтобы понять, почему, рас смотрим упрощенную  версию подразумеваемого для Button шаблона элемен та управления:

<ControlTemplate TargetType=’{x:Type Button}’>

<Border Background=’{TemplateBinding Background}’ x:Name=’border’>

<ContentPresenter />

</Border>

<ControlTemplate.Triggers>

<Trigger Property=’IsPressed’ Value=’True’>

<Setter Property=’Background’ Value=’Red’ TargetName=’border’ />

</Trigger>

</ControlTemplate.Triggers>

</ControlTemplate>

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

Источник: К. Андерсон  Основы  Windows Presentation Foundation. Пер. с англ. А. Слинкина — М.: ДМК Пресс, 2008 — 432 с.: ил.

По теме:

  • Комментарии