天天看點

如何使用資源檔案

昨天突發奇想,向寫一個類似于MSN 的自定義個性化窗體,今天在實踐的過程中,發現在實作資源檔案時就遇到了困難。

就不錯,而且其中也注解了:

  注意:ResourceManager rm = new ResourceManager ( " Res.My " , Assembly.GetExecutingAssembly ( ) ) ;語句中,構造函數的第一個參數Res.My 由兩部分構成,Res表示測試工程的命名空間,My表示資源檔案名My.resources的根名稱,即點号有前部分My。

然而自己在實踐過程中,還是對baseName 的了解發生一個錯誤。由于自己使用C#寫程式的,剛開始認為添加資源檔案很簡單,就直接用ResourceManager區讀取.resouce檔案使用,但是失敗了。

//private const System.String RESOURCE_BASE_NAME = "Component.Popup";

this.ResourceDirectory = @"E:/projects/Popup/src/Resources";

 System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-cn");

this.resMng = System.Resources.ResourceManager.CreateFileBasedResourceManager(RESOURCE_BASE_NAME, this.ResourceDirectory, typeof(PopupCtl));

随後又換成ResourceWriter 來自己寫.resource 檔案,調用還是出現了問題。

this.CreateResource();

this.resMng = new System.Resources.ResourceManager("Component.Popup.Resources", System.Reflection.Assembly.GetExecutingAssembly());

Image img = (System.Drawing.Image)this.resMng.GetObject("btn_close") //這句報錯,說是找不到btn_close

private void CreateResource()

 {

     System.Resources.ResourceWriter rw = new System.Resources.ResourceWriter(RESOURCE_FILE_NAME);

     Image img = Image.FromFile(@"E:/projects/Work/UpdateUI/Test/Component/btn_close.gif");

      rw.AddResource("btn_close", img);

     rw.Generate();

      rw.Close();

}

不知道自己是在那裡錯誤了,找了1個小時的網上資料也沒有結果。剛好電視在放《唐伯虎點秋香》,哈哈,又看到了“剛出爐的孝子大拍賣”,“美女”,“這是你們逼我的——龜波氣功”。哈哈,經典就是經典。

看完了電視再來看看程式,無聊的翻看着程式所在的目錄發現在obj/Debug目錄下有這個一個檔案Component.Popup.Properties.Resources.resouce

看着這個檔案怎麼這麼熟悉,好像是資源檔案,而且檔案名中多了一個properties ,這個不是vs2005中的屬性目錄嗎? 難道說是程式自動把資源檔案所在目錄也加入到了名稱中?

傳回程式,修改了baseName 的字元串為 Component.Popup.Properties.Resources ,運作程式,一切ok。

暈,怎麼會這樣?到底是怎麼回事?馬上上Microsfot查找,找到了這片文章:

<a href="http://www.microsoft.com/china/community/program/originalarticles/techdoc/how_resourcefile.mspx">http://www.microsoft.com/china/community/program/originalarticles/techdoc/how_resourcefile.mspx</a>

其中有這麼一段:

如何準确的定義資源檔案的邏輯位置

我想這是許多人最關注的一段了!在這裡作者将解說如何正确的填寫 ResouceManager(String, Assembly) 這個 constructor,還有如何正确的填寫 Assembly.GetManifestResourceStream(String),因為它們兩個的原理是相同的。看過了上面的描述,到了這裡就簡單多了。這裡主要讨論的是怎麼填寫那個 String。這個 String 就是資源的完整名,一個完整名由它的名字空間和檔案名前部分(BaseName)組成。例如,如果預設名字空間(root namespace)是 DefaultNamespace,資源檔案的名字是 Strings.en-US.resources,那麼它的完整名就是 DefaultNamespace.Strings。這個很簡單,不過怎樣确定名字空間呢?這就有些奇怪了,因為 C# 的編譯器與 VB.NET 的編譯器有些不同。作者在這裡分别給出兩個編譯器怎樣給嵌入資源自動添加命名空間:

C#

它自動添加 default namespace(與 root namespace 相同),但也添加子檔案夾的名字。例如,在 Subfolder 子檔案夾下放的資源檔案 Strings.en-US.resources,它的完整名是 default namespace + subfolder + base name = DefaultNamespace.Subfolder.Strings

VB.NET

在 VB.NET 中就很簡單了,它自動給嵌入資源添加 root namespace。不管你在哪個子檔案夾中放置資源檔案,資源檔案的完整名永遠是 root namespace + base name。

根據上面的描述,如果我們使用 C#,用 VS.NET 在 NewFolder 這個子檔案夾中添加了一個叫 Images.resources 的資源檔案,那麼我們應該用以下代碼擷取這些資源,假設 default namespace 是 MyDefault:

ResourceManager res = new ResourceManager("MyDefault.NewFolder.Images", this.GetType().Assembly);

但如果我們用 VB.NET 的話,就應該這樣:

Dim res As New ResourceManager("MyDefault.Images", Me.GetType().Assembly)

看完上面的解釋才發現自己的正确性,再更改CreateResource,運作,ok。一路綠燈。哈哈,成功了。

總結一下:

1、不要眼高手低。雖然看到資源檔案很簡單,大體上你可能知道,但是不妨動手試一下,也許你遇到一個強有力的對手的;

2、對于困難的問題可以适當休息後再解決;

3、《唐伯虎點秋香》經典還是經典。