在這個地球村的時代下,一個軟體要廣泛讓世界各地的大眾使用就要考慮到各地的語言文化。我們常常在一些大型的國際網站上看到可以選擇語言,然後網站就會轉換成對應的語言,這個機制為全球化(Globalization),在 .Net是有此機制的,所以今天限量就要來簡單說明如何在 .Net的程式中加入 Globalization。
Globalization的實作有幾個主要關鍵,CultureInfo 與 Resources File(.resx)。
CultureInfo 是 .Net中的一個類別,它代表的是一個文化,在日期, 字串, 數字相關類別中的方法可以看的到它的一些蹤影。
Resources File 的副檔名為 .resx 是 .Net專案中集中資源的地方,它可以放置影像, 二進制數值, 字串, 圖示, 音訊與其他種類型的資源,Resource File 與 Culture 可以搭配使用,各種 Culture 的可有對應的 Resource File,其命名規則如下:[File Name].[Culture Code].resx,例如:ErrorCode.zh-TW.resx, ErrorCode.en-US.resx。
接下來就來按照步驟加入 Globalization 吧:
首先先加入預設 Culture 的 Resources File,在專案按右鍵 [加入新項目] => 選擇 [Resources File]加入。
*注意:預設的 Resource File 一定要加入,因為VS會根據這個檔案自動產生處理資源的類別,所以如果沒有的話就會無法取得資源檔。
接著編輯資源檔。
再來依照同樣步驟加入另一個 Culture 的 Resources File 並編輯。
*注意:各 Culture 內的資源數量與 Name 要一致,因為程式會使用 Name 去抓取對應的資源。
建立完成後可以看到VS幫我們建立了一個 CodeMsg.Designer.cs 的檔案,這個檔案就是讓我們可以在開發時期去呼叫的資源類別,類別名稱與 Resources File 檔名相同,剛剛所定義的字串皆可以直接調用取得值。
CodeMsg.Designer.cs
另外,如果不想用產生出來的資源檔類別來存取資源的時候,可以自己使用ResourceManager 的 GetString 或 GetXXX 的方式來取得,因為VS把資源的Name Build 成 Property,這樣動態使用起來比較不方便。
以下為使用 ResourceManager 取得資源的範例程式:
Program.cs
執行結果:
Globalization的實作有幾個主要關鍵,CultureInfo 與 Resources File(.resx)。
CultureInfo 是 .Net中的一個類別,它代表的是一個文化,在日期, 字串, 數字相關類別中的方法可以看的到它的一些蹤影。
Resources File 的副檔名為 .resx 是 .Net專案中集中資源的地方,它可以放置影像, 二進制數值, 字串, 圖示, 音訊與其他種類型的資源,Resource File 與 Culture 可以搭配使用,各種 Culture 的可有對應的 Resource File,其命名規則如下:[File Name].[Culture Code].resx,例如:ErrorCode.zh-TW.resx, ErrorCode.en-US.resx。
接下來就來按照步驟加入 Globalization 吧:
首先先加入預設 Culture 的 Resources File,在專案按右鍵 [加入新項目] => 選擇 [Resources File]加入。
*注意:預設的 Resource File 一定要加入,因為VS會根據這個檔案自動產生處理資源的類別,所以如果沒有的話就會無法取得資源檔。
接著編輯資源檔。
再來依照同樣步驟加入另一個 Culture 的 Resources File 並編輯。
*注意:各 Culture 內的資源數量與 Name 要一致,因為程式會使用 Name 去抓取對應的資源。
建立完成後可以看到VS幫我們建立了一個 CodeMsg.Designer.cs 的檔案,這個檔案就是讓我們可以在開發時期去呼叫的資源類別,類別名稱與 Resources File 檔名相同,剛剛所定義的字串皆可以直接調用取得值。
CodeMsg.Designer.cs
//------------------------------------------------------------------------------ //// This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //------------------------------------------------------------------------------ namespace TestSolution { using System; ////// A strongly-typed resource class, for looking up localized strings, etc. /// // This class was auto-generated by the StronglyTypedResourceBuilder // class via a tool like ResGen or Visual Studio. // To add or remove a member, edit your .ResX file then rerun ResGen // with the /str option, or rebuild your VS project. [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class CodeMsg { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal CodeMsg() { } ////// Returns the cached ResourceManager instance used by this class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("TestSolution.CodeMsg", typeof(CodeMsg).Assembly); resourceMan = temp; } return resourceMan; } } ////// Overrides the current thread's CurrentUICulture property for all /// resource lookups using this strongly typed resource class. /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } ////// Looks up a localized string similar to 錯誤. /// internal static string REPLY_ERROR { get { return ResourceManager.GetString("REPLY_ERROR", resourceCulture); } } ////// Looks up a localized string similar to 正確. /// internal static string REPLY_OK { get { return ResourceManager.GetString("REPLY_OK", resourceCulture); } } } }
另外,如果不想用產生出來的資源檔類別來存取資源的時候,可以自己使用ResourceManager 的 GetString 或 GetXXX 的方式來取得,因為VS把資源的Name Build 成 Property,這樣動態使用起來比較不方便。
以下為使用 ResourceManager 取得資源的範例程式:
Program.cs
class Program { static void Main(string[] args) { Console.WriteLine("Enter culture code: "); var culture = Console.ReadLine(); if(!string.IsNullOrWhiteSpace(culture)) { // 取得目前主執行續並設定ResourceManager的Culture Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(culture); } Console.WriteLine(string.Format("Culture: {0}", CultureInfo.CurrentUICulture.Name)); // 產生ResourceManager實體 var rm = new ResourceManager("TestSolution.CodeMsg", Assembly.GetExecutingAssembly()); // 取得資源檔中的Name為REPLY_OK的字串 var str = rm.GetString("REPLY_OK"); Console.WriteLine(string.Format("REPLY_OK: {0}", str)); Console.Read(); } }
執行結果:
留言
張貼留言