WinForms 版 Windows 功能区,第 10 部分 – 使用图像






4.94/5 (12投票s)
在本文中,我将介绍如何在功能区中使用图像。
这系列 CodeProject 文章基于我首先在我的 博客上发表的一系列帖子。
在本帖中,我们将回顾功能区框架的图像术语,并了解如何在 WinForms 应用程序中静态和动态地设置图像。
更多详情请参见 MSDN 上的 指定功能区图像资源。
大图像与小图像
许多功能区控件允许您指定图像。例如:Button
、ComboBox
和 Spinner
。
这些控件中的大多数都有两个属性,一个用于大图像,一个用于小图像。功能区框架会根据可用屏幕空间和您对组缩放的定义来选择其中一种尺寸。
大图像通常尺寸为 32x32 像素,小图像通常尺寸为 16x16 像素。
我之所以说“通常”,是因为这可能会改变。实际图像尺寸应取决于您选择的分辨率和 DPI 设置。Microsoft 推荐的图像尺寸如下:
DPI |
小图像 |
大图像 |
96 dpi |
16x16 像素 |
32x32 像素 |
120 dpi |
20x20 像素 |
40x40 像素 |
144 dpi |
24x24 像素 |
48x48 像素 |
192 dpi |
32x32 像素 |
64x64 像素 |
功能区控件的图像通过 LargeImage
和 SmallImage
属性暴露。
高对比度模式
高对比度是 Windows 的一项辅助功能,专为视力障碍人士设计。可以通过按:Left ALT + Left SHIFT + PRINT SCREEN 来打开/关闭。
该模式的主要作用是更改系统颜色,以便相邻颜色具有高对比度。
现在,为了在您的应用程序中支持高对比度模式,功能区框架暴露了两个额外的属性:LargeHighContrastImage
和 SmallHighContrastImage
,允许您专门为该模式设置图像。以下是一个应用程序在高对比度模式下通常外观的示例。
静态设置图像
我们已经提到了有 4 个图像属性:LargeImage
、SmallImage
、LargeHighContrastImage
和 SmallHighContrastImage
。图像的尺寸取决于当前的系统设置。因此,我们需要一种方法来为这些场景提供不同的图像。方法如下:
<Command Name="cmdCut" Id="1008" LabelTitle="Cut">
<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>
如果您没有指定所有这些图像,功能区框架将使用可用的图像并根据其需求调整尺寸。当然,自己提供图像是获得最佳结果的方法。
动态设置图像
在本节中,我们将学习如何动态设置按钮的图像。最终结果将如下所示:
这次图像无济于事,您需要自行运行以查看代码效果。
“Swap Once”按钮演示了以编程方式设置 LargeImage
属性的最简单方法。
“Swap Image”按钮演示了如何根据推荐尺寸设置图像。
我在 RibbonLib.Ribbon
类中添加了一个名为 ConvertToUIImage
的新函数。用法如下:
void _buttonDropA_OnExecute(PropertyKeyRef key,
PropVariantRef currentValue, IUISimplePropertySet commandExecutionProperties)
{
// load bitmap from file
Bitmap bitmap = new System.Drawing.Bitmap(@"..\..\Res\Drop32.bmp");
bitmap.MakeTransparent();
// set large image property
_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
方法实际做的是创建一个名为 UIRibbonImageFromBitmapFactory
的功能区框架 COM 对象实例,该对象实现了 IUIImageFromBitmap
。此接口提供了一个函数,用于将给定的 HBITMAP
(位图句柄)包装为 IUIImage
接口。
功能区图像属性与这些 IUIImage
实例一起工作。请注意,UIRibbonImageFromBitmapFactory
的实际创建是在 RibbonLib.Ribbon InitFramework
方法中完成的。
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
控件添加了辅助类。这些辅助类可以轻松更改选项卡、组和按钮的属性。Button
类还公开了一个 OnExecute
事件,方便您响应按钮单击。
一如既往,本帖的结果是另一个关于在 WinForms 应用程序中使用功能区特性的示例。请在 WinForms 版 Windows 功能区 中找到它。
暂时就到这里,
Arik Poznanski。