.Net自定义控件之ToolboxBitmap元数据的设置

写.Net自定义控件有一段时间了,一日突然发现工具箱里的那个蓝色齿轮图标越看越不爽。怎么办?换!

于是查了一下MSDN按照它的做法试了N次都行不通。

百度、Google 也查了,但是不知道是网上的那些个解决办法没有被写清楚,还是我的理解能力的问题。

这个问题还是没解决。因为有新的任务下来,这个问题一直被悬着没解决,最近因为项目的原因需要自己开发特定功能的控件。

该是解决这个问题的时候了。研究了一个早上总于搞定了。现在把我得到的结论写在这里,希望对大家有所帮助。

不啰嗦了,进入正题。

首先,选择一张大小为16*16的bmp位图,尺寸超过16*16会被缩放。

而且也不仅仅只是支持bmp的图片,至于究竟支持那些格式的图片,有兴趣的朋友可以去研究下。

注意:位图的左下角的颜色将被设置为透明色。

准备:解决方案:Widgets

         项目名称:Widgets.Windows

     控件名称:Expander

     两个Visual Studio 2008实例:一个用于打开解决方案Widgets,另一个打开解决方案Testing

补充:因为Widgets.Windows是Windows窗体应用程序的控件库,所以解决方案Testing中建立的项目也必须是Windows窗体应用程序。

 

ToolboxBitmap有三个重载,依次展开就很容易把问题解释清楚了。

 

重载一:

重载一

个人不推荐用这种方式,因为imageFile要使用图片的绝对路径(试了几次相对路径,但没见到效果)。

而且控件的图标会随着你路径所指定的那张图片的改变而改变。

做一下实验就知道了。首先,我们准备两张图片,如下图:

Expander的元数据设置如下:

重载一 Expander元数据

编译控件库Widgets.Windows,然后把编译后的Widgets.Windows.dll文件拖到 Testing 的工具箱里。就会看到以下效果。 

不要感到奇怪为什么有两个Expander,而且图标还不一样,这是因为我第一次把它拖到工具箱后,就把路径 "Z:\Expander.bmp” 指向的图片换掉了,

然后再把Widgets.Windows.dll拖到工具箱里,无需再次编译 Expander 的图标随之改变。

  

重载二:

重载二

准备一张图片,并命名为Expander.bmp,把它添加到Widgets.Windows项目中,然后把它的属性设置为“嵌入的资源”。

文件结构如下图:

Expander的元数据设置如下:

重载二 Expander元数据

 编译Widgets.Windows项目,先不急着把它拖到Testing的工具箱里,用Reflector看一下它生成后的文件结构:

可以看到图片被加上了"Widgets.Windows"前缀,首先要说明的是"Widgets.Windows"是这个项目的默认命名空间。

目前我们能得到的结论就是:嵌入的资源编译后会被自动加上该项目的默认命名空间名称。

之前看过一篇文章,说为了避免这个问题可以手动打开项目文件把默认命名空间删掉就可以了。

个人不推荐这么做,而且Visual Studio 2008也不允许你这么做,因为默认命名空间的重要性,是不需要我在这里说明的。

好了,回到正题上来,这里给大家看这张图片是为了与下面一种方法对比的。

现在把编译后的Widgets.Windows.dll文件拖到 Testing 的工具箱里,就可以看到你设置的图标了。这个就不截图了,因为我是比较懒滴。

  

重载三:

重载三

还是一样,准备一张图片,并命名为Expander.bmp,把它添加到Widgets.Windows项目中,然后把它的属性设置为“嵌入的资源”。

但是这次不一样的是:图片不是在项目的根目录中。

文件结构图如下:

Expander的元数据设置如下:

重载三 Expander元数据

编译Widgets.Windows项目,再次用Reflector看一下它生成后的文件结构:

这次我们可以看到,Expander.bmp编译后的的不但被加上了默认命名空间名称,还加上了该图片的文件夹的名字。

但是我的元数据中并没有写上它被编译出来的全称"Widgets.Windows.Resources.Icon.Expander.bmp",而是"Resources.Icon.Expander.bmp"

也就是说我把默认命名空间去掉了,不要怀疑,把编译后的Widgets.Windows.dll文件拖到 Testing 的工具箱里,是可以看到预期的图标的。

这里也不截图了,原因我不说你也知道,呵呵!

之前看过一篇文章,说什么要把元数据设置为“解决方案名称+项目名称+图片文件夹名称+文件名”。

那时候还在摸索阶段,所以按他的方法试了又试却始终达不到想要的效果。后来认真一想,解决方案只是拿来管理项目的,关项目里的类什么事?

所以把解决方案名称去掉了,但还是没有用。然后想起第二种重载:当图片在项目的根目录下时,是不需要设置图片名称的,

难道项目名称也是不需要的?所以索性就把项目名称也去掉了。终于达到了想要的效果了!

再说了“解决方案名称+项目名称+图片文件夹名称+文件名”这种说法是不够正确的,项目名称只是项目名称,正真编译出来图片加上的前缀

既不是程序集的名称也不是项目名称,而是是默认命名空间名称。除非你的项目名称和你这个项目的默认命名空间名称相同,这种说法才成立!

我能达到效果的原因只不过是我的习惯是项目名称、程序集名称、默认命名空间名称三者通常设为一样的罢了。

  

总结:

个人是比较喜欢重载三的,原因有以下三点:

一、比较灵活,图片的名称不一定要与控件类的名称相同,虽然说相同比较好一些;

二、稳定。不像重载一那样需要去硬盘上找图片,我是把我的移动硬盘指定为Z:盘,难道当我把这个控件发布出去时,

     也一定要让使用者在Ta的Z:盘放一张图片吗?

三、资源统一管理。第二种重载虽然方便、简洁,但它有着太多的限制,图片的文件名必须与控件类名一致、图片必须位于项目的根目录下,

     这样一来当同一个项目中控件达到一定的数量时,势必会为文件的管理带来不便。

 

就一个ToolboxBitmap元数据的设置就花了这么大的篇幅来解释,希望高手们不要嫌我啰嗦哦,

我只是想把问题解释得更清楚,为需要帮助的人,提供一点点信息而已。

 

今天(2009年5月20日)抽空写了一个简单的例子

https://files.cnblogs.com/zys529/ToolboxIcon.rar

MD5:FB9897A8A49A677715C2080447BE5572

希望对大家有所帮助。

 

原文地址:http://www.cnblogs.com/zys529/archive/2009/04/26/1443854.html

 

近期发现有些朋友转载了这篇日志,

但大部分转载过去后代码格式发生了紊乱,图片也不能正常显示。

为了不影响读者的阅读和学习,请转载的朋友把本文的链接地址一并加上,谢谢!!!

当然,这一段废话就不用加上去了^_^

posted @ 2009-04-26 12:33  Nabbiit  阅读(4037)  评论(8编辑  收藏  举报