ImageList組件用了很久,但是一直不太清楚它的實現原理,今天專門特意花了時間倒騰了下,終於弄明白了!於是在這里和大家分享下!

在設計頁面中打卡工具箱-組件 找到ImageList組件,將它直接拖到頁面上,將會自動在設計也生成初始化代碼,如下:
1 //.Designer.cs設計頁面自動生成的初始化代碼 2 private System.Windows.Forms.ImageList imageList1; 3 // 4 // imageList1 5 // 6 this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream"))); 7 this.imageList1.TransparentColor = System.Drawing.Color.Transparent; 8 this.imageList1.Images.SetKeyName(0, "open.ico"); 9 this.imageList1.Images.SetKeyName(1, "save.ico"); 10 this.imageList1.Images.SetKeyName(2, "退出.ico"); 11 this.imageList1.Images.SetKeyName(3, "delete.ico");
在設計頁面打開屬性窗口,點擊Images后面的三個小點按鈕打開 圖像集合編輯器 如下圖:

點擊添加按鈕將會直接從本地加載圖片到ImageList中,這里就有一個問題,添加的圖片是以什么形式添加的呢?是路徑還是二級制流?如果是圖片那應該在右邊的屬性窗口能看到圖片的路徑才對,而這里看不到,說明圖片應該是已二進制流或者說是圖片流的形式保存的。而通過參考之前的設計頁的初始化代碼也可以看出,程序在初始化的時候是直接用resources對象加載圖片流的,而這里是看不到它是從哪里加載的,那么首先要搞明白resources對象是什么東東?先看下這個對象的聲明:
1 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmImportCardInfo)); 2 // 摘要: 3 // 提供組件或對象的枚舉資源的簡單功能。System.ComponentModel.ComponentResourceManager 類是一個 System.Resources.ResourceManager。 4 public class ComponentResourceManager : ResourceManager
從以上代碼可以看出其實resources是類ComponentResourceManager的對象,而這個類又是繼承自ResourceManager類,很明顯它就是一個用於管理本地資源的一個類。弄清楚了這個,就知道我們添加進去的圖片是存在本地資源中的。而我們的每個窗體在設計的時候,如果添加了圖片等資源類的對象時會自動生成一個文件,也就是拓展名為.resx的文件,如果沒有,那么我們的每個窗體一般只有兩個文件:.cs文件和.Designer.cs文件。
在項目中雙擊打開.resx文件,顯示可視化界面如圖:

在窗體中添加的資源,默認都會在該文件中,除非在項目中另外添加了Resources.resx資源類文件。從上圖可以看出添加的資源類名稱和之前在設計頁自動生成的代碼引入的資源名稱是一致的:resources.GetObject("imageList1.ImageStream"),所以到這里我們就已經確定了添加的圖片確實是保存在.resx文件中的。不過在這個頁面我們還看不到它的值。不過,我們可以用記事本打開的方式打開該文件(愛動手的程序猿最可怕
),顯示如圖:

可以看出,它的值是以base64編碼的形式存儲在文件中的。所以,所有添加的圖片實際上是直接保存在項目中,而不是保存地址。如果將ImageList直接Copy到其他頁面,那么也會在相應窗體創建這樣一個資源文件用於保存圖片。
我的網站原文鏈接:淺談ImageList
