Нашли ошибку или опечатку? Выделите текст и нажмите

Поменять цветовую

гамму сайта?

Поменять
Обновления сайта
и новые разделы

Рекомендовать в Google +1

Множество уровней стилей

39
1

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

Например, предположим, что группе элементов управления требуется назначить один и тот же шрифт без применения к каждому из них одного и того же стиля. В этом случае можно разместить нужные элементы управления в одной панели (или в контейнере другого типа) и установить стиль контейнера. При условии установки свойств, которые используют средство наследования значений, эти значения будут передаваться дочерним элементам. К числу свойств, которые поддерживают такую модель, относятся IsEnabled, IsVisible, Foreground и все свойства, связанные со шрифтом.

В других ситуациях требуется создать стиль, основанный на другом стиле. Для использования наследования стилей необходимо установить атрибут BasedOn соответствующего стиля. Например, рассмотрим два следующих стиля:

<Style x:Key="MyButtonStyle">
            <Setter Property="Control.FontFamily" Value="Calibri"></Setter>
            <Setter Property="Control.FontSize" Value="18"></Setter>
            <Setter Property="Control.FontWeight" Value="Bold"></Setter>
            <Setter Property="Control.Padding" Value="5"></Setter>
            <Setter Property="Control.Margin" Value="5"></Setter>
</Style>
<Style x:Key="TiledStyle" BasedOn="{StaticResource MyButtonStyle}">
           <Setter Property="Control.Background">
                <Setter.Value>
                    <ImageBrush TileMode="Tile" ViewportUnits="Absolute"
                                Viewport="0 0 32 32" ImageSource="cry.png"
                                Opacity="0.3"></ImageBrush>
                </Setter.Value>
            </Setter>
</Style>

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

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

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

Создание стиля основанного на другом стиле

Хотя наследование стилей на первый взгляд выглядит очень удобным приемом, обычно оно не стоит затрачиваемых усилий. Причина в том, что наследование стилей влечет за собой те же проблемы, что и наследование кода, т.е. приводит к образованию зависимостей, которые делают приложение более хрупким. Например, в случае использования приведенной выше разметки одни и те же характеристики шрифта обязательно должны сохраняться для обоих стилей. Модификация стиля MyButtonStyle приводит также к изменению стиля TiledStyle — если только явно не добавить дополнительные средства установки, переопределяющие унаследованные значения.

Эта проблема тривиальна в примере с двумя стилями, но существенно усложняется при наследовании стилей в реальных приложениях. Обычно стили делятся на категории на основе типов содержимого и ролей, которые это содержимое исполняет. Например, приложение для продаж может включать в себя стили наподобие ProductTitleStyle, ProductTextStyle, HighlightQuoteStyle, NavigationButtonStyle и т.д. Если основать стиль ProductTitleStyle на ProductTextStyle (возможно потому, что они оба разделяют один и тот же шрифт), то возникнут проблемы, когда позже понадобится применить к стилю ProductTextStyle настройки, которые не должны применяться к стилю ProductTitleStyle (например, разные поля). В таком случае придется определить эти настройки в стиле ProductTextStyle и явно переопределить их в стиле ProductTitleStyle. В конечном итоге это приведет к получению гораздо более сложной модели и весьма небольшому количеству настроек, которые действительно используются многократно.

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