Содержание
При работе с интерфейсом приложения нам придётся часто использовать различные цвета и оттенки для элементов управления. В WPF и XAML, в частности, для этих целей используются специальные объекты — кисти (Brush
), используя которые мы можем устанавливать цвета для отдельных свойств элементов, а также использовать в качестве заполнителей области элемента различные объекты и изображения. В этой части мы рассмотрим доступные нам Кисти в XAML
Свойства, определяющие цветовое оформление XAML-элементов
Для визуальных элементов являющихся наследниками типа Control
доступны следующие свойства цвета:
Свойство | Тип | Описание |
Background |
Brush |
Кисть, которая используется для заливки фона элемента управления. Значение по умолчанию — Transparent |
Foreground |
Кисть, которая заливает основной цвет элемента управления. По умолчанию используется цвет шрифта диалоговых окон системы. | |
BorderBrush |
Кисть, которая используется для заливки границы элемента управления. Значение по умолчанию — Transparent |
Все эти три свойства имеют один и тот же тип — Brush
(кисть). При этом, в WPF и XAML нам доступны различные наследники этого типа, позволяющие делать как сплошную, так и. например, градиентную заливки.
Кисти в XAML
Иерархию объектов типа Brush можно представить в виде следующей схемы:
Рассмотрим различные кисти, которые мы можем использовать в наших приложениях WPF.
Кисть SolidColorBrush и цвет в XAML
Определяя цвет любого из представленных выше свойств, мы особо и не задумываемся над тем, что фактически используем объект типа SolidColorBrush
, которые представляет кисть со сплошной заливкой. Нам достаточно использовать одно из зарезервированных названий цветов, например, Red, Blue, Green и т.д. или задать цвет в формате #FF00FFFF, чтобы получить заливку цветом како-либо части XAML-элемента. Вся работа по созданию необходимых объектов производится при обработке XAML-документа.
При этом стоит помнить, что любой цвет XAML представляется экземпляром структуры Color
из пространства имен System.Windows.Media, которая описывает любой цвет или его оттенок с использованием четырех составляющих: непрозрачность цвета (A — альфа-канал), красный цвет (R), зеленый цвет (G) и синий цвет (B). Значение каждой составляющей изменяется в диапазоне от 0 до 255. Если составляющие R, G, B равны 0, то это соответствует черному цвету, если все три составляющие равны 255, то это соответствует белому цвету. Если значение альфа-канала (A) равно 255, то это соответствует полностью непрозрачному цвету, а 0 — полностью прозрачному (Transparent
) и такой цвет невидим.
Если для задания цвета используется зарезервированное название, например, Red
или используется шестнадцатеричное значение, состоящее из трех цифр, то такой цвет получает значение альфа-канала равное 255 и формируется полностью непрозрачный цвет.
Используя возможные способы задания цвета в XAML, мы можем, например, определить фон окна приложения следующими способами:
используя зарезервированное название цвета
<Window x:Class="WpfApp1.MainWindow" ... Background="Blue"> </Window>
используя шестнадцатеричное определение цвета
<Window x:Class="WpfApp1.MainWindow" ... Background="#0000FF"> </Window>
В любом случае, здесь никак не прослеживается то, что мы используем объект SolidColorBrush
. Для того, чтобы иметь возможность явным образом определить и кисть и цвет в коде XAML мы должны использовать элементы свойств. Например, определим цвет фона окна следующим образом:
<Window x:Class="WpfApp1.MainWindow" ... <Window.Background> <SolidColorBrush>Blue</SolidColorBrush> </Window.Background> </Window>
Здесь мы использовали в качестве содержимого для элемента SolidColorBrush
имя цвета — Blue
. При необходимости, мы также можем определить каждый компонент цвета отдельно, например, так:
<Window x:Class="WpfApp1.MainWindow" ... <Window.Background> <SolidColorBrush> <SolidColorBrush.Color> <Color R="#00" G="#00" B="#FF" A="#FF"/> </SolidColorBrush.Color> </SolidColorBrush> </Window.Background> </Window>
Или использовать десятичную систему счисления для задания свойств цвета:
<Window x:Class="WpfApp1.MainWindow" ... <Window.Background> <SolidColorBrush> <SolidColorBrush.Color> <Color R="0" G="0" B="255" A="125"/> </SolidColorBrush.Color> </SolidColorBrush> </Window.Background> </Window>
В приведенных выше примерах мы явно определили объект SolidColorBrush
у которого одним из свойств выступает свойство Color
одноименного типа, которое мы также задаем, используя элемент свойства:
<Color R="0" G="0" B="255" A="125"/>
Более того, мы можем заменить декларацию свойства Color
и таким вариантом:
<Window.Background> <SolidColorBrush> <SolidColorBrush.Color> <Color> Blue </Color> </SolidColorBrush.Color> </SolidColorBrush> </Window.Background>
или использовать шестнадцатеричное определение цвета. Используя различные варианты определения цвета, кисти SolidColorBrush
и свойства позиционирования элементов, мы можем создать, например, вот такой внешний вид окна:
<Window x:Class="WpfApp1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApp1" mc:Ignorable="d" Title="MainWindow" Height="450" Width="800"> <Grid> <Label Content="XAML" FontSize="96" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Arial Black" FontWeight="Bold" Foreground="Red"/> <Label Content="Это не WPF" FontSize="80" VerticalAlignment="Center" HorizontalAlignment="Center" FontFamily="Arial Black" FontWeight="Bold" > <Label.Foreground> <SolidColorBrush> <SolidColorBrush.Color> <Color R="0" G="255" B="0" A="180"></Color> </SolidColorBrush.Color> </SolidColorBrush> </Label.Foreground> </Label> </Grid> </Window>
Здесь два элемента типа Label
накладываются друг на друга и у одного из них для цвета текста применен цвет с альфа-каналом. В результате мы увидим следующий текст:
SolidColorBrush
— это только один из наследников абстрактного класса Brush
. Рассмотрим другие типы кистей, которые мы можем применить в WPF и XAML.
Кисти в XAML: LinearGradientBrush
Объект LinearGradientBrush
представляет кисть для заливки с использованием линейного градиента (плавного перехода от одного цвета к другому). Тип LinearGradientBrush
предоставляет нам следующие свойства:
Свойство | Тип | Описание |
Gradient |
GradientStopCollection |
Коллекция объектов типа GradientStop , определяющих точки перехода градиента |
Start |
Point |
Начальная точка градиента. По умолчанию (0,0) . |
End |
Point |
Конечная точка градиента. По умолчанию (1,1) |
Spread |
GradientSpreadMethod |
Тип метода рисования градиента. Может принимать следующие значения:
|
Opacity |
double |
Прозрачность |
Продемонстрируем использование этих свойств на примере. Для того, чтобы создать градиентную заливку, нам необходимо задать направление градиента, а также точки перехода в виде коллекции объектов GradientStop
. По умолчанию направление градиента — диагональ. Например, используем линейный градиент для заливки окна приложения:
<Window x:Class="WpfApp1.MainWindow" ...> <Window.Background> <LinearGradientBrush> <GradientStopCollection> <GradientStop Color="Red" Offset="0"></GradientStop> <GradientStop Color="Green" Offset="0.5"></GradientStop> <GradientStop Color="Blue" Offset="1"></GradientStop> </GradientStopCollection> </LinearGradientBrush> </Window.Background> </Window>
Здесь мы оставили направление градиента по умолчанию — от верхнего левого угла к нижнему правому и определили три точки перехода (три объекта GradientStop
). У каждой точки мы указали цвет и значение Offset
(смещение). Таким образом, наш градиент будет следующим: в точке Start
цвет будет красным с плавным переходом в зеленый до точки (0.5, 0.5). В точке (0.5, 0.5) цвет зеленый с плавным переходом к синему. В точке (1,1) цвет синий. В результате мы увидим следующую заливку окна:
При желании, мы можем изменить направление градиента, например, вот так:
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5"> <GradientStopCollection> <GradientStop Color="Red" Offset="0"></GradientStop> <GradientStop Color="Green" Offset="0.5"></GradientStop> <GradientStop Color="Blue" Offset="1"></GradientStop> </GradientStopCollection> </LinearGradientBrush>
Теперь градиент будет горизонтальным — начинаться от середины левой границы и заканчиваться на середине правой границы:Отдельное внимание стоит уделить такому свойству как
Spread
. Определим градиент следующим образом:
<LinearGradientBrush StartPoint="0,0.5" EndPoint="0.5,0.5"> <GradientStopCollection> <GradientStop Color="Red" Offset="0"></GradientStop> <GradientStop Color="Green" Offset="0.5"></GradientStop> <GradientStop Color="Blue" Offset="1"></GradientStop> </GradientStopCollection> </LinearGradientBrush>
Градиент теперь заканчивается на середине окна, а свойство Spread
по умолчанию равно Pad
, то есть, начиная с точки (0.5, 0.5) заливка формы будет определяться цветом на конце вектора градиента:
Значение Reflect повторяет градиент в обратном направлении:
а значение Repeat
— в том же направлении:
Использовать градиент мы можем не только для свойства Background элемента, но и для любых других свойств с типом Brush, например, используем градиент для заливки рамки у кнопки:
<Button Width="400" Height="200" Content="Моя кнопка" BorderThickness="15"> <Button.BorderBrush> <LinearGradientBrush StartPoint="0,0.5" EndPoint="0.5,0.5" SpreadMethod="Reflect"> <GradientStopCollection> <GradientStop Color="Red" Offset="0"></GradientStop> <GradientStop Color="Yellow" Offset="0.5"></GradientStop> <GradientStop Color="Blue" Offset="1"></GradientStop> </GradientStopCollection> </LinearGradientBrush> </Button.BorderBrush> </Button>
Кисти в XAML: RadialGradientBrush
Кисть RadialGradientBrush
также, как и LinearGradientBrush
закрашивает заданную область, используя градиент, но распространение цвета идёт во всех направлениях от точки начала градиента до границы эллипса градиента. У класса RadialGradientBrush
определены следующие свойства:
Свойство | Тип | Описание |
Gradient |
GradientStopCollection |
Коллекция объектов типа GradientStop , определяющих точки перехода градиента |
Spread |
GradientSpreadMethod |
Тип метода рисования градиента. Может принимать следующие значения:
|
Center |
Point |
Центр эллипса закрашиваемой области |
GradientOrigin |
Point |
Начало радиального градиента |
RadiusX |
double |
Горизонтальный радиус эллипса |
RadiusY |
double |
Вертикальный радиус эллипса |
Продемонстрируем действие новых для нас свойств на следующем примере:
<Window x:Class="WpfApp1.MainWindow" ...> <Window.Background> <RadialGradientBrush GradientOrigin="0.5,0.5" Center="0.5,0.5" RadiusX="0.5" RadiusY="0.5"> <GradientStopCollection> <GradientStop Color="Red" Offset="0"></GradientStop> <GradientStop Color="Yellow" Offset="0.5"></GradientStop> <GradientStop Color="Blue" Offset="1"></GradientStop> </GradientStopCollection> </RadialGradientBrush> </Window.Background> </Window>
В результате, мы увидим градиент, распространяющийся из центра окнаИзменим положение внешнего эллипса для градиента:
<Window.Background> <RadialGradientBrush GradientOrigin="0.5,0.5" Center="0.9,0.5" RadiusX="0.7" RadiusY="0.5"> <GradientStopCollection> <GradientStop Color="Red" Offset="0"></GradientStop> <GradientStop Color="Yellow" Offset="0.5"></GradientStop> <GradientStop Color="Blue" Offset="1"></GradientStop> </GradientStopCollection> </RadialGradientBrush> </Window.Background>
Кисти в XAML: ImageBrush
Кисть ImageBrush
— это наследник класса TileBrush
и заполняет область растровым изображением с предоставляет нам следующие свойства:
Свойство | Тип | Описание |
Image |
ImageSource |
Изображение, которое используется для заполнения области |
Opacity |
double |
Степень прозрачности |
Stretch |
Stretch |
Определяет правила растягивания изображения и может принимать следующие значения: None , Uniform , UniformToFill , Fill |
Tile |
TileMode |
Определяет способ заполнения области и может принимать следующие значения: FlipX , FlipXY , FlipY , None , Tile |
Viewbox |
Rect |
Определяет прямоугольный фрагмент изображение, которое помещается на базовую плитку |
Viewport |
Rect |
Определяет расположение и размеры прямоугольника, который выделяется в области вывода для базовой плитки |
ViewportUnits |
BrushMappingMode |
Определяет относительность или абсолютность чисел, определяющих значения для Viewport |
Для демонстрации работы ImageBrush
нам потребуется какое-либо изображение. Создайте в проекте папку Images и разместите в ней любое изображение. Например, я буду использовать вот такую картинку:
а структура проекта будет вот такой:
Теперь изменим код MainWindow.xaml следующим образом:
<Window x:Class="WpfApp1.MainWindow" ...> <Window.Background> <ImageBrush ImageSource="/images/wpf.png"></ImageBrush> </Window.Background> </Window>
В результате получим вот такой вид окна приложения:
В данном случае, свойство Stretch
равно Fill
— изображение растягивается, занимая всё доступное пространство области. Ниже представлено как будет выглядеть окно при различных вариантах свойства Stretch
:
Stretch = "None"
. Изображение не растягивается
Stretch="Uniform"
. Изображение растягивается с сохранением пропорций:Stretch="UniformToFill"
. Изображение растягивается с сохранением пропорций сторон, однако заполняет все доступное пространство области:
Если для ImageBrush
необходимо использовать только часть изображения, то нам необходимо задать значения свойства Viewbox
, которое представляет собой тип Rect
. Для задания этого свойства нам необходимо определить координаты левого верхнего угла, а также длину и ширину прямоугольника. Все величины по умолчанию задаются в относительных единицах. Например, выделим только часть изображения и растянем его на всю доступную область с сохранением пропорций:
<Window.Background> <ImageBrush Viewbox="0.25, 0.1, 0.5,0.5" Stretch="UniformToFill" ImageSource="/images/wpf.png"></ImageBrush> </Window.Background>
В результате получим вот такой вид окна:
Свойство Viewport
используется в том случае, если нам необходимо «размножить» изображение для заполнения области. Например, изменим свойства ImageBrush следующим образом:
<Window.Background> <ImageBrush Viewbox="0.25, 0.1, 0.5,0.5" Viewport="0,0,0.1,0.1" TileMode="Tile" Stretch="Uniform" ImageSource="/images/wpf.png"></ImageBrush> </Window.Background>
Теперь вся область окна будет заполнена отдельными фрагментами изображения, как показано на рисунке ниже:
Свойство TileMode
может принимать следующие значения:
Кисти в XAML: DrawingBrush
Кисть DrawingBrush
также, как и ImageBrush
может применяться для заполнения области каким-либо изображением, но является более сложной в использовании, так как позволяет использовать не только изображения, но и различные геометрические фигуры, текст и т.д.
Класс DrawingBrush
предоставляет нам следующее дополнительное (по сравнению с ImageBrush
) свойство:
Свойство | Тип | Описание |
Drawing |
Drawing |
Объект, описывающий содержимое кисти |
Сам по себе, класс Drawing
является абстрактным, поэтому мы можем использовать только его наследников. Ниже представлены наследники класса Drawing
и их описание
Тип | Описание |
DrawingGroup |
Коллекция элементов типа Drawing , с которой можно работать как с одним изображением, то есть ко всем членам коллекции применяются одни и те же свойства |
GeometryDrawing |
Совокупность геометрических фигур, декларируемых свойством Geometry . Здесь используются одни и те же свойства Brush и Pen для всех фигур коллекции |
GliphRunDrawing |
Представляет текст в виде объекта типа GliphRun |
ImageDrawing |
Фрагмент графического изображения |
VideoDrawing |
Воспроизводит мультимедиа файл. Для видеофайла выполняет визуализацию в прямоугольнике, определенном свойством Rect |
Продемонстрируем один из примеров использования этой кисти в приложении WPF:
<Window x:Class="WpfApp1.MainWindow" ...> <Window.Background> <DrawingBrush> <DrawingBrush.Drawing> <GeometryDrawing Brush="LightBlue"> <GeometryDrawing.Geometry> <GeometryGroup> <EllipseGeometry RadiusX="12.5" RadiusY="25" Center="25,50" /> <EllipseGeometry RadiusX="12.5" RadiusY="25" Center="50,50" /> <EllipseGeometry RadiusX="12.5" RadiusY="25" Center="75,50" /> </GeometryGroup> </GeometryDrawing.Geometry> <GeometryDrawing.Pen> <Pen Thickness="1" Brush="Gray" /> </GeometryDrawing.Pen> </GeometryDrawing> </DrawingBrush.Drawing> </DrawingBrush> </Window.Background> </Window>
Здесь мы используем три эллипса, чтобы заполнить область окна. При этом, для всех трех фигур используются одни и те же свойства заливки, толщины рамки и её цвета. В конструкторе окно будет выглядеть следующим образом:
Кисти в XAML: VisualBrush
Кисть VisualBrush
использует в качестве заполнителя изображение какого-либо визуального элемента. Эта кисть предоставляет нам следующие свойства:
Свойство | Тип | Описание |
AutoLayoutContent |
bool |
Указывает на соответствие экземпляра VisualBrush макету декларированного в нем объекта Visual |
Visual |
Visual |
Содержимое кисти |
Например, используем в качестве содержимого кисти кнопку:
<Window.Background> <VisualBrush AutoLayoutContent="True" Stretch="Uniform"> <VisualBrush.Visual> <Button Content="Hello, World"/> </VisualBrush.Visual> </VisualBrush> </Window.Background>
В итоге, кнопка растянется на всё доступное пространство, сохранив при этом свои пропорции
Итого
Для визуального оформления элементов в XAML мы можем использовать такие свойства элементов как Background
, Foreground
и BorderBrush
, каждое из которых представляется объектом Brush (кисть). В XAML и WPF мы можем использовать шесть различных типов кистей — SolidBrush
, LinearGradientBrush
, RadialGradientBrush
, DrawingBrush
, ImageBrush
, VisualBrush
.