Windows Ribbon в .NET-приложениях (ч.4)

Автор: Topol Суббота, Май 5th, 2012 Нет комментариев

Рубрика: Операционные системы

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

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

Хотелось бы оговориться, что на момент написания этой статьи последней версией библиотеки 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);
}

За кулисами
Что на самом деле выполняет метод SetColors:

  • Получает интерфейс IPropertyStore из IUIFramework (который представляет фреймворк ленты)
  • Создаёт 3 переменных PropVariant, которые будут содержать 3 нужных нам цвета
  • Преобразовывает цвета: RGB -> HSL -> HSB -> uint (см. следующий подзаголовок)
  • Задаёт соответствующие свойства с преобразованными значениями цветов

 

Код:
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();
}

Цветовые форматы
Я не погружался в мир цветовых форматов, поэтому дам лишь краткую справку.

RGB — хорошо известный цветовой формат, который мы, разработчики, любим и понимаем.

RGB может быть конвертирован в HSL. Это, должно быть, обычное преобразование, или, как Майкрософт написала здесь, «легко выполнимое большинством программ для редактирования фотографий». На этой странице Майкрософт также предоставляет формулы для преобразования HSL в HSB. Здесь вы можете найти код, написанный на C#, преобразующий RGB в HSL и обратно.

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

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

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

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

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

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

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

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

DPI Маленькое изображение Большое изображение
96 точек/дюйм 16×16 пикселей 32×32 пикселей
120 точек/дюйм 20×20 пикселей 40×40 пикселей
144 точек/дюйм 24×24 пикселей 48×48 пикселей
192 точек/дюйм 32×32 пикселей 64×64 пикселей

Изображения для элемента управления ленты представляются через свойства LargeImage и SmallImage.

Режим высокой контрастности
Высокая контрастность — это специальная возможность Windows, разработанная для людей с ослабленным зрением. Его можно включить или выключить, нажав сочетание клавиш «Левый ALT + Левый SHIFT + PRINT SCREEN». Основное действие этого режима — изменение системных цветов так, чтобы схожие цвета имели высокую контрастность.

Теперь, чтобы ваше приложение поддерживало режим высокой контрастности, фреймворк ленты обладает двумя специальными свойствами: LargeHighContrastImage и SmallHighContrastImage, которые позволяют задать изображения специально для данного режима. Вот пример того, как приложение обычно выглядит в режиме высокой контрастности:

Статическое задание изображений
Итак, мы упомянули, что у нас есть 4 свойства для изображений: LargeImage, SmallImage, LargeHighContrastImage и SmallHighContrastImage, — и что размер изображений зависит от текущих настроек системы.

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

Код:
<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>

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

Динамическое задание изображений
В этом подзаголовке мы рассмотрим, как можно динамически задавать изображения для кнопки. Конечный результат будет выглядеть примерно так:

На этот раз рисунок не поможет, вам придётся самостоятельно запустить приложение, чтобы увидеть, как работает код. Кнопка «Заменить единожды» демонстрирует простейший способ программного задания свойства LargeImage. Кнопка «Сменить изображение» демонстрирует, как задавать изображение согласно рекомендуемому размеру.

Я добавил новую функцию в класс RibbonLib.Ribbon, названную ConvertToUIImage. Вот, как она используется:

Код:
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);
}

Если вы хотите задать изображение, имеющее соответствующий текущим настройкам DPI размер, чтобы фреймворк ленты не изменял размер вашего изображения, вы должны узнать значение SystemInformation.IconSize.Width.

Размер больших изображений должен быть (SystemInformation.IconSize.Width) x (SystemInformation.IconSize.Width), а маленьких — (SystemInformation.IconSize.Width/2) x (SystemInformation.IconSize.Width/2).

Вот образец того, как задавать изображение согласно настройкам Windows:

Код:
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);
}

За кулисами
На самом деле, метод ConvertToUIImage создаёт экземпляр COM-объекта фреймворка ленты под названием UIRibbonImageFromBitmapFactory, который реализует IUIImageFromBitmap. Этот интерфейс предоставляет функцию для обработки заданного HBITMAP (дескриптора точечного рисунка) как интерфейса IUIImage.

Свойства изображений ленты работают с этими экземплярами IUIImage. Заметьте, что фактически UIRibbonImageFromBitmapFactory создаётся в методе InitFramework класса RibbonLib.Ribbon.

Код:
public IUIImage ConvertToUIImage(Bitmap bitmap)
{
if (_imageFromBitmap == null)
{
return null;
}

IUIImage uiImage;
_imageFromBitmap.CreateImage(bitmap.GetHbitmap(), Ownership.Transfer, out uiImage);

return uiImage;
}

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

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

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

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

Источник: thevista.ru

Оставить комментарий

Чтобы оставлять комментарии Вы должны быть авторизованы.

Похожие посты