ImageList组件用了很久,但是一直不太清楚它的实现原理,今天专门特意花了时间倒腾了下,终于弄明白了!于是在这里和大家分享下!

浅谈ImageList-LMLPHP

在设计页面中打卡工具箱-组件 找到ImageList组件,将它直接拖到页面上,将会自动在设计也生成初始化代码,如下:

 //.Designer.cs设计页面自动生成的初始化代码
private System.Windows.Forms.ImageList imageList1;
//
// imageList1
//
this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
this.imageList1.Images.SetKeyName(, "open.ico");
this.imageList1.Images.SetKeyName(, "save.ico");
this.imageList1.Images.SetKeyName(, "退出.ico");
this.imageList1.Images.SetKeyName(, "delete.ico");

在设计页面打开属性窗口,点击Images后面的三个小点按钮打开 图像集合编辑器 如下图:

浅谈ImageList-LMLPHP

点击添加按钮将会直接从本地加载图片到ImageList中,这里就有一个问题,添加的图片是以什么形式添加的呢?是路径还是二级制流?如果是图片那应该在右边的属性窗口能看到图片的路径才对,而这里看不到,说明图片应该是已二进制流或者说是图片流的形式保存的。而通过参考之前的设计页的初始化代码也可以看出,程序在初始化的时候是直接用resources对象加载图片流的,而这里是看不到它是从哪里加载的,那么首先要搞明白resources对象是什么东东?先看下这个对象的声明:

 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmImportCardInfo));
// 摘要:
// 提供组件或对象的枚举资源的简单功能。System.ComponentModel.ComponentResourceManager 类是一个 System.Resources.ResourceManager。
public class ComponentResourceManager : ResourceManager

从以上代码可以看出其实resources是类ComponentResourceManager的对象,而这个类又是继承自ResourceManager类,很明显它就是一个用于管理本地资源的一个类。弄清楚了这个,就知道我们添加进去的图片是存在本地资源中的。而我们的每个窗体在设计的时候,如果添加了图片等资源类的对象时会自动生成一个文件,也就是拓展名为.resx的文件,如果没有,那么我们的每个窗体一般只有两个文件:.cs文件和.Designer.cs文件。

在项目中双击打开.resx文件,显示可视化界面如图:

浅谈ImageList-LMLPHP

在窗体中添加的资源,默认都会在该文件中,除非在项目中另外添加了Resources.resx资源类文件。从上图可以看出添加的资源类名称和之前在设计页自动生成的代码引入的资源名称是一致的:resources.GetObject("imageList1.ImageStream"),所以到这里我们就已经确定了添加的图片确实是保存在.resx文件中的。不过在这个页面我们还看不到它的值。不过,我们可以用记事本打开的方式打开该文件(爱动手的程序猿最可怕浅谈ImageList-LMLPHP),显示如图:

浅谈ImageList-LMLPHP

可以看出,它的值是以base64编码的形式存储在文件中的。所以,所有添加的图片实际上是直接保存在项目中,而不是保存地址。如果将ImageList直接Copy到其他页面,那么也会在相应窗体创建这样一个资源文件用于保存图片。

我的网站原文链接:浅谈ImageList

04-15 08:36