Опрос
Вы участвуете в программе Windows Insider?
Популярные новости
Обсуждаемые новости

30.09.2010 20:23 | deeper2k

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

В этот раз мы узнаем, как можно изменить цвет ленты, а также как работать с изображениями, используемыми на ленте.

Хотелось бы оговориться, что на момент написания этой статьи последней версией библиотеки Windows Ribbon for WinForms оставалась версия 2.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. Это, должно быть, обычное преобразование, или, как Майкрософт написала здесь, "легко выполнимое большинством программ для редактирования фотографий". На этой странице Майкрософт также предоставляет формулы для преобразования HSL в HSB. Здесь вы можете найти код, написанный на C#, преобразующий RGB в HSL и обратно.

Наконец, HSB конвертируется в uint простым сопоставлением значений, почти как при конвертации RGB в uint.

Все эти подробности я заключил во вспомогательном классе, названном RibbonLib.ColorHelper.

Очередной образец под именем 07-RibbonColor подводит итог данной части статьи.


Работа с изображениями
В этой части статьи мы рассмотрим терминологию изображений в фреймворке ленты и посмотрим, как статически и динамически задавать изображения в вашем приложении WinForms.

Более подробно об этом можно прочитать в статье Задание ресурсов изображений ленты на MSDN.


Большие изображения против маленьких
Многие элементы управления ленты позволяют задать для них изображение. Например: кнопка (Button), выпадающий список (ComboBox) и счётчик (Spinner).

Большинство этих контролов имеют два свойства, одно для большого изображения и второе — для маленького. Фреймворк ленты выберет один из этих размеров в зависимости от доступного места на экране и назначенных группе размеров.

Большое изображение обычно имеет размер 32x32 пикселей, а маленькое — 16x16. Я говорю "обычно", поскольку это может разниться. На самом деле, размеры изображений должны зависеть от ваших настроек разрешения и DPI. Майкрософт рекомендует следующие размеры изображений:

DPI96 точек/дюйм120 точек/дюйм144 точек/дюйм192 точек/дюйм
Маленькое изображениеБольшое изображение
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]

Бонус
По образу и подобию моей реализации вспомогательных классов для элементов управления ленты счётчик (Spinner) и выпадающий список (ComboBox), я добавил вспомогательные классы для контролов вкладка (Tab), группа (Group) и кнопка (Button). Эти "помощники" позволят вам легко изменять свойства вкладок, групп и кнопок. Класс для кнопки также предоставляет событие OnExecute, которое облегчает способ реагирования на нажатия кнопки.

Примечание переводчика: Данный абзац относится исключительно к процессу разработки Ариком библиотеки Windows Ribbon for WinForms.

Как всегда, результатом данной части статьи является очередное приложение-образец.


Заключение
На этом пока всё. Эта статья вышла небольшой и несложной. В следующей же статье мы займёмся довольно объёмной темой — галереями на ленте Windows, а помимо них мы рассмотрим такие элементы управления ленты, как флажок (CheckBox) и выключатель (ToggleButton).


Sgt.Riggs, TheVista.Ru Team,
Сентябрь 2010

Комментарии

Не в сети

Исходные сообщения в блоге Арика Познански, переведённые в этой статье:

Windows Ribbon for WinForms, Part 9 – Changing Ribbon Colors
Windows Ribbon for WinForms, Part 10 – Working With Images

30.09.10 22:59
0
Для возможности комментировать войдите в 1 клик через

По теме

Акции MSFT
420.55 0.00
Акции торгуются с 17:30 до 00:00 по Москве
Все права принадлежат © ms insider @thevista.ru, 2022
Сайт является источником уникальной информации о семействе операционных систем Windows и других продуктах Microsoft. Перепечатка материалов возможна только с разрешения редакции.
Работает на WMS 2.34 (Страница создана за 0.041 секунд (Общее время SQL: 0.017 секунд - SQL запросов: 53 - Среднее время SQL: 0.00032 секунд))
Top.Mail.Ru