Windows Ribbon в .NET-приложениях (ч.4)
В предыдущей статье мы научились создавать на ленте вкладки с группами, кнопку справки, а также рассмотрели элементы управления счётчик и раскрывающийся (выпадающий) список. Также я упомянул об ошибке в обработке значений счётчика, поэтому если у вас возникли проблемы при работе со счётчиком, загляните в заключение
В этот раз мы узнаем, как можно изменить цвет ленты, а также как работать с изображениями, используемыми на ленте.
Хотелось бы оговориться, что на момент написания этой статьи последней версией библиотеки
Что ж, начнём.
Изменение цвета ленты: введение
В этой части статьи я хочу рассказать о возможности изменения основных цветов ленты. Заметьте, что вы не можете изменять цвет конкретного элемента, только всей ленты целиком.
Мы можем изменить 3 цвета:
- Фоновый цвет
- Цвет выделения
- Цвет текста
Вот образец "раскрашенной" ленты:
Как это сделать?
В классе RibbonLib.Ribbon библиотеки Windows Ribbon for WinForms есть специальный метод. Вот пример его использования:
private void Form1_Load(object sender, EventArgs e)
{
// инициализация фреймворка ленты
_ribbon.InitFramework(this);
// задание цветов ленты
_ribbon.SetColors(Color.Wheat, Color.IndianRed, Color.BlueViolet);
}
ianRed, Color.BlueViolet);
}[/code]
За кулисами
Что на самом деле выполняет метод SetColors:
- Получает интерфейс IPropertyStore из IUIFramework (который представляет фреймворк ленты)
- Создаёт 3 переменных PropVariant, которые будут содержать 3 нужных нам цвета
- Преобразовывает цвета: RGB -> HSL -> HSB -> uint (см. следующий подзаголовок)
- Задаёт соответствующие свойства с преобразованными значениями цветов
[code]public void SetColors(Color background, Color highlight, Color text)
{
if (_framework == null)
{
return;
}
IPropertyStore propertyStore = (IPropertyStore)_framework;
PropVariant backgroundColorProp = new PropVariant();
PropVariant highlightColorProp = new PropVariant();
PropVariant textColorProp = new PropVariant();
uint backgroundColor = ColorHelper.HSB2uint(
ColorHelper.HSL2HSB(
ColorHelper.RGB2HSL(background)));
uint highlightColor = ColorHelper.HSB2uint(
ColorHelper.HSL2HSB(
ColorHelper.RGB2HSL(highlight)));
uint textColor = ColorHelper.HSB2uint(
ColorHelper.HSL2HSB(
ColorHelper.RGB2HSL(text)));
backgroundColorProp.SetUInt(backgroundColor);
highlightColorProp.SetUInt(highlightColor);
textColorProp.SetUInt(textColor);
propertyStore.SetValue(ref RibbonProperties.UI_PKEY_GlobalBackgroundColor,
ref backgroundColorProp);
propertyStore.SetValue(ref RibbonProperties.UI_PKEY_GlobalHighlightColor,
ref highlightColorProp);
propertyStore.SetValue(ref RibbonProperties.UI_PKEY_GlobalTextColor,
ref textColorProp);
propertyStore.Commit();
}[/code]
Цветовые форматы
Я не погружался в мир цветовых форматов, поэтому дам лишь краткую справку.
RGB — хорошо известный цветовой формат, который мы, разработчики, любим и понимаем.
RGB может быть конвертирован в HSL. Это, должно быть, обычное преобразование, или, как Майкрософт написала
Наконец, HSB конвертируется в uint простым сопоставлением значений, почти как при конвертации RGB в uint.
Все эти подробности я заключил во вспомогательном классе, названном RibbonLib.ColorHelper.
Очередной образец под именем 07-RibbonColor подводит итог данной части статьи.
Работа с изображениями
В этой части статьи мы рассмотрим терминологию изображений в фреймворке ленты и посмотрим, как статически и динамически задавать изображения в вашем приложении WinForms.
Более подробно об этом можно прочитать в статье
Большие изображения против маленьких
Многие элементы управления ленты позволяют задать для них изображение. Например: кнопка (Button), выпадающий список (ComboBox) и счётчик (Spinner).
Большинство этих контролов имеют два свойства, одно для большого изображения и второе — для маленького. Фреймворк ленты выберет один из этих размеров в зависимости от доступного места на экране и назначенных группе размеров.
Большое изображение обычно имеет размер 32x32 пикселей, а маленькое — 16x16. Я говорю "обычно", поскольку это может разниться. На самом деле, размеры изображений должны зависеть от ваших настроек разрешения и DPI. Майкрософт рекомендует следующие размеры изображений:
Маленькое изображение | Большое изображение |
16x16 пикселей | 32x32 пикселей |
20x20 пикселей | 40x40 пикселей |
24x24 пикселей | 48x48 пикселей |
32x32 пикселей | 64x64 пикселей |
Изображения для элемента управления ленты представляются через свойства LargeImage и SmallImage.
Режим высокой контрастности
Высокая контрастность — это специальная возможность Windows, разработанная для людей с ослабленным зрением. Его можно включить или выключить, нажав сочетание клавиш "Левый ALT + Левый SHIFT + PRINT SCREEN". Основное действие этого режима — изменение системных цветов так, чтобы схожие цвета имели высокую контрастность.
Теперь, чтобы ваше приложение поддерживало режим высокой контрастности, фреймворк ленты обладает двумя специальными свойствами: LargeHighContrastImage и SmallHighContrastImage, которые позволяют задать изображения специально для данного режима. Вот пример того, как приложение обычно выглядит в режиме высокой контрастности:
Статическое задание изображений
Итак, мы упомянули, что у нас есть 4 свойства для изображений: LargeImage, SmallImage, LargeHighContrastImage и SmallHighContrastImage, — и что размер изображений зависит от текущих настроек системы.
Таким образом, нам нужен способ передать приложению различные изображения для этих сценариев. Вот он:
[code]<Command Name="cmdCut" Id="1008" LabelTitle="Вырезать">
<Command.LargeImages>
<Image Source="res/CutLargeImage32.bmp" MinDPI="96" />
<Image Source="res/CutLargeImage40.bmp" MinDPI="120" />
<Image Source="res/CutLargeImage48.bmp" MinDPI="144" />
<Image Source="res/CutLargeImage64.bmp" MinDPI="192" />
</Command.LargeImages>
<Command.SmallImages>
<Image Source="res/CutSmallImage16.bmp" MinDPI="96" />
<Image Source="res/CutSmallImage20.bmp" MinDPI="120" />
<Image Source="res/CutSmallImage24.bmp" MinDPI="144" />
<Image Source="res/CutSmallImage32.bmp" MinDPI="192" />
</Command.SmallImages>
<Command.LargeHighContrastImages>
<Image Source="res/CutLargeImage32HC.bmp" MinDPI="96" />
<Image Source="res/CutLargeImage40HC.bmp" MinDPI="120" />
<Image Source="res/CutLargeImage48HC.bmp" MinDPI="144" />
<Image Source="res/CutLargeImage64HC.bmp" MinDPI="192" />
</Command.LargeHighContrastImages>
<Command.SmallHighContrastImages>
<Image Source="res/CutSmallImage16HC.bmp" MinDPI="96" />
<Image Source="res/CutSmallImage20HC.bmp" MinDPI="120" />
<Image Source="res/CutSmallImage24HC.bmp" MinDPI="144" />
<Image Source="res/CutSmallImage32HC.bmp" MinDPI="192" />
</Command.SmallHighContrastImages>
</Command>[/code]
Если вы не зададите все эти изображения, фреймворк ленты будет использовать доступные изображения и изменять их размер согласно потребностям. Разумеется, лучший вариант — предоставить все изображения вручную.
Динамическое задание изображений
В этом подзаголовке мы рассмотрим, как можно динамически задавать изображения для кнопки. Конечный результат будет выглядеть примерно так:
На этот раз рисунок не поможет, вам придётся самостоятельно запустить приложение, чтобы увидеть, как работает код. Кнопка "Заменить единожды" демонстрирует простейший способ программного задания свойства LargeImage. Кнопка "Сменить изображение" демонстрирует, как задавать изображение согласно рекомендуемому размеру.
Я добавил новую функцию в класс RibbonLib.Ribbon, названную ConvertToUIImage. Вот, как она используется:
[code]void _buttonDropA_OnExecute(PropertyKeyRef key, PropVariantRef currentValue, IUISimplePropertySet commandExecutionProperties)
{
// загрузить точечный рисунок из файла
Bitmap bitmap = new System.Drawing.Bitmap(@"..\..\Res\Drop32.bmp");
bitmap.MakeTransparent();
// задать свойство большого изображения
_buttonDropA.LargeImage = _ribbon.ConvertToUIImage(bitmap);
}[/code]
Если вы хотите задать изображение, имеющее соответствующий текущим настройкам DPI размер, чтобы фреймворк ленты не изменял размер вашего изображения, вы должны узнать значение SystemInformation.IconSize.Width.
Размер больших изображений должен быть (SystemInformation.IconSize.Width) x (SystemInformation.IconSize.Width), а маленьких — (SystemInformation.IconSize.Width/2) x (SystemInformation.IconSize.Width/2).
Вот образец того, как задавать изображение согласно настройкам Windows:
[code]void _buttonDropB_OnExecute(PropertyKeyRef key, PropVariantRef currentValue, IUISimplePropertySet commandExecutionProperties)
{
List<int> supportedImageSizes = new List<int>() { 32, 48, 64 };
Bitmap bitmap;
StringBuilder bitmapFileName = new StringBuilder();
int selectedImageSize;
if (supportedImageSizes.Contains(SystemInformation.IconSize.Width))
{
selectedImageSize = SystemInformation.IconSize.Width;
}
else
{
selectedImageSize = 32;
}
exitOn = !exitOn;
string exitStatus = exitOn ? "on" : "off";
bitmapFileName.AppendFormat(@"..\..\Res\Exit{0}{1}.bmp", exitStatus, selectedImageSize);
bitmap = new System.Drawing.Bitmap(bitmapFileName.ToString());
bitmap.MakeTransparent();
_buttonDropB.LargeImage = _ribbon.ConvertToUIImage(bitmap);
}[/code]
За кулисами
На самом деле, метод ConvertToUIImage создаёт экземпляр COM-объекта фреймворка ленты под названием UIRibbonImageFromBitmapFactory, который реализует IUIImageFromBitmap. Этот интерфейс предоставляет функцию для обработки заданного HBITMAP (дескриптора точечного рисунка) как интерфейса IUIImage.
Свойства изображений ленты работают с этими экземплярами IUIImage. Заметьте, что фактически UIRibbonImageFromBitmapFactory создаётся в методе InitFramework класса RibbonLib.Ribbon.
[code]public IUIImage ConvertToUIImage(Bitmap bitmap)
{
if (_imageFromBitmap == null)
{
return null;
}
IUIImage uiImage;
_imageFromBitmap.CreateImage(bitmap.GetHbitmap(), Ownership.Transfer, out uiImage);
return uiImage;
}[/code]
Бонус
По образу и подобию моей реализации вспомогательных классов для элементов управления ленты счётчик (
Примечание переводчика: Данный абзац относится исключительно к процессу разработки Ариком библиотеки Windows Ribbon for WinForms.
Как всегда, результатом данной части статьи является очередное приложение-образец.
Заключение
На этом пока всё. Эта статья вышла небольшой и несложной. В следующей же статье мы займёмся довольно объёмной темой — галереями на ленте Windows, а помимо них мы рассмотрим такие элементы управления ленты, как флажок (CheckBox) и выключатель (ToggleButton).
Сентябрь 2010
Комментарии
Исходные сообщения в блоге Арика Познански, переведённые в этой статье:
По теме
- Видео-курсы от MS: Разработка приложений виртуальной и расширенной реальности на платформе Microsoft
- ECMA JavaScript 6: Объекты
- Как просто создать приложение для iPhone
- Разработка приложений под Windows Phone 8
- Индексированное хранилище, часть 2
- Индексированное хранилище, часть 1
- Начала Metro-программирования: создание настраиваемых приложений (ч.2)
- Начала Metro-программирования: создание настраиваемых приложений (ч.1)
- Начала Metro-программирования: создание компонентов WinRT (ч.3)
- Начала Metro-программирования: создание компонентов WinRT (ч.2)