WPF, пензля фону та переднього плану

Усі елементи управління мають фон (background) та передній план (foreground). Як правило, фоном є поверхня елемента управління (наприклад, біла або сіра область усередині кнопки), а переднім планом текст. У WPF колір (але не вміст) цих двох областей визначається за допомогою властивостейBackground таForeground відповідно.

Природно очікувати, що властивості Background та Foreground повинні використовувати об'єкти кольору, як у програмах на основі Windows Forms. Однак насправді ці властивості використовують універсальніший об'єкт — Brush (пензель). Він дозволяє заливати вміст фону та переднього плану суцільним кольором (за допомогою пензля SolidColorBrush) або чимось екзотичним (наприклад, використовуючи пензлі LinearGradientBrush або TileBrush).

Вказівка ​​кольорів у коді

Припустимо, що ви хочете встановити всередині кнопки cmd поверхню блакитного кольору. Ось код, що дозволяє це зробити:

Цей код створює новий об'єкт SolidColorBrush із кольором, вказаним за допомогою статичної властивості класу Colors. (Імена засновані на назвах кольорів, які підтримуються більшістю веб-браузерів.) Потім цей пензель визначається як фоновий пензель кнопки, внаслідок чого фон кнопки стає світло-блакитним.

Такий спосіб оформлення кнопки не дуже зручний. Він задає фоновий колір кнопки в її звичайному стані (не натиснута), але не змінює колір, який з'являється при натисканні на кнопці (зазвичай темніший сірий колір). Щоб налаштувати всі нюанси відображення кнопок, слід ознайомитись із шаблонами.

Можна також користуватися системними кольорами (вони можуть вибиратися з переваг користувача) з переліку System.Windows.SystemColors. Наприклад:

Оскільки системні пензлівикористовуються часто, система SystemColors пропонує також готові властивості, що повертають об'єкти SolidColorBrush. Нижче показано, як їх застосовувати:

В обох цих прикладах є невелика проблема. Якщо системний колір буде змінено після виконання цього коду, кнопка не буде оновлена, а новий колір не буде застосований. По суті цей код робить миттєвий знімок поточного кольору або пензля.

Щоб програма могла змінювати себе у відповідь зміни у конфігурації, необхідно застосовувати динамічні ресурси. Класи Colors та SystemColors пропонують зручні скорочення, проте це не єдиний спосіб задати колір. Ви можете, наприклад, створити об'єкт Color, вказавши значення R, G і В (червоної, зеленої та синьої складових). Кожне з цих значень є числом діапазону 0-255.

Можна зробити колір частково прозорим, використовуючи значення альфа-каналу і викликавши методColor.FromArgb(). Значення альфа-каналу, що дорівнює 255, відповідає повній непрозорості, а значення 0 - повної прозорості:

Стандарт RGB корисний, оскільки застосовується у багатьох інших програмах. Наприклад, можна отримати RGB-значення кольору в програмі для малювання і використовувати цей колір у WPF-додатку. Однак не виключено, що інші пристрої (наприклад, принтери) можуть підтримувати ширший спектр кольорів. З цієї причини було створено альтернативний стандарт scRGB, у якому кожен компонент кольору (альфа-канал, червоний, зелений та синій) представлений 64-бітовими значеннями.

Структура класу Color у WPF підтримує обидва підходи. Вона включає як набір стандартних властивостей RGB (A, R, G та В), так і набір властивостей scRGB (ScA, ScR, ScG та ScB). Ці властивості пов'язані між собою, тому якщо задати властивість R, відповідно зміниться і властивість ScR.

Взаємозв'язок між значеннями RGB та значеннями scRGB не є лінійним. Значення 0 в системі RGB відповідає значенню 0 в scRGB, 255 RGB відповідає 1 в scRGB, а всі значення в діапазоні 0-255 в RGB представлені в scRGB як десяткові значення з діапазону від 0 до 1.

Завдання квітів у XAML

Завдання кольору фону або переднього плану в XAML можна скористатися зручним скороченням. Замість визначення об'єкта Brush можна вказати назву або значення кольору. Компілятор WPF автоматично створить об'єкт SolidColorBrush з вибраним кольором і буде використовувати цей об'єкт для фону або переднього плану. Ось приклад із використанням імені кольору:

Він еквівалентний наступному багаторядковому фрагменту:

Якщо потрібний інший тип пензля (наприклад, LinearGradientBrush), для малювання фону потрібно використовувати довшу форму.

Якщо необхідний код кольору, доведеться користуватися менш зручним синтаксисом, в якому значення R, G і В надаються у шістнадцятковому форматі. Доступні два формати: #rrggbb або #aarrggbb (вони відрізняються тим, що другий формат містить значення альфа-каналу). Для завдання значень A, R, G і В потрібно лише по дві цифри, оскільки всі вони подаються в шістнадцятковій формі. Нижче наведено приклад, який створює той самий колір, що й у попередньому фрагменті коду, за допомогою формату aarrggbb:

Тут значенням альфа-каналу є FF (255), значенням червоної складової - FF (255), а зелена та синя складові дорівнюють 0.

Кисті підтримують автоматичне повідомлення про зміни. Тобто якщо прикріпити кисть до елемента керування та змінити його, елемент керування оновлює себе відповідним чином. Це можливо тому, що пензля є нащадками класу System.Windows.Freezable. Назва цьогокласу (freezable - заморожуваний) пояснюється тим, що всі такі об'єкти мають два стани: стан, що змінюється, і стан тільки для читання ("заморожене").

Background та Foreground – не єдині властивості, які можна визначити за допомогою пензля. Властивості BorderBrush та BorderThickness дозволяють намалювати рамку навколо елементів керування (і деяких інших елементів на кшталт Border).

ВластивістьBorderBrush приймає вказану кисть, а властивістьBorderThickness — ширину рамки в одиницях, що не залежать від пристрою. Щоб рамка стала видимою, необхідно встановити обидві властивості.

Деякі елементи керування не підтримують використання властивостей BorderBrush та BorderThickness. Об'єкт Button ігнорує їх повністю, оскільки визначає своє тло та рамку за допомогою декоратора ButtonChrome. Однак кнопці можна надати новий вигляд (із вказаною рамкою) за допомогою шаблонів.