C# 實現多語言支持的本地化(System.Globalization名稱空間)
當前位置:點晴教程→知識管理交流
→『 技術文檔交流 』
? System.Globalization名稱空間System.Globalization 名稱空間包含了所有的區域性類和區域類,以支持不同的日期格式、不同 的數字格式,甚至如GregorianCalendar 類、HebrewCalendar 類和JapaneseCalendar 類等表示的不同 日歷。使用這些類可以根據不同的地區顯示不同的表示法。 Unicode問題因為一個Unicode 字符有16 位,所以共有65536 個Unicode 字符。這對于當前在信息技術中使 用的所有語言夠用嗎?例如,漢語就需要80 000 多個字符。但是,Unicode 可以解決這個問題。使 用Unicode 必須區分基本字符和組合字符。可以給一個基本字符添加若干個組合字符,組成一個可 顯示的字符或一個文本元素。 例如,冰島的字符Ogonek,就可以使用基本字符0x006F(拉丁小字母o)、組合字符0x0328(組 合Ogonek)和0x0304(組合Macron)組合而成,組合字符在0x0300~0x0345 之間定 義,對于美國和歐洲市場,預定義字符有助于處理特殊的字符。字符Ogonek 也可以用預定義字符 0x01ED 來定義。 StringInfo 類的靜態方法 一個顯示字符可以包含多個Unicode 字符。要解決這個問題,如果編寫的應用程 序要在國際市場銷售,就不應使用數據類型char,而應使用string。string 可以包含由 基本字符和組合字符組成的文本元素,但char 不能。 區域性和區域世界分為多個區域性和區域,應用程序必須知道這些區域性和區域的差異。區域性是基于用戶 的語言和區域性習慣的一組偏愛特性。RFC 1766(www.ietf.org/rfc/rfc1766.txt)定義了區域性的名稱, 這些名稱根據語言和國家或區域的不同在世界各地使用。例如en-AU、en-CA、en-GB 和en-US 分 別用于表示澳大利亞、加拿大、英國和美國的英語。 在 System.Globalization 名稱空間中,最重要的類是CultureInfo。這個類表示區域性,定義了日 歷、數字和日期的格式,以及和區域性一起使用的排序字符串。 RegionInfo 類表示區域設置(如貨幣),說明該區域是否使用米制系統。在某些區域中,可以使用 多種語言。例如,西班牙區域就有Basque(eu-ES)、Catalan(ca-ES)、Spanish(es-ES)和Galician(gl-ES) 區域性。類似于一個區域可以有多種語言,一種語言也可以在多個區域使用,例如,墨西哥、西班 牙、危地馬拉、阿根廷和秘魯等都使用西班牙語。 特定、中立和不變的區域性在.NET Framework 中使用區域性,必須區分3 種類型:特定、中立和不變的區域性。 特定的區域性與真正存在的區域性相關,這種區域性用上一節介紹的RFC 1766 定義。特定的 區域性可以映射到中立的區域性。例如,de 是特定區域性de-AT、de-DE、de-CH 等的中立區域性, de 是德語(German【Deutsch】)的簡寫,AT、DE 和CH 分別是奧地利(Austria)、德國(Germany)和瑞 士(Switzerland)等國家的簡寫。 在翻譯應用程序時,通常不需要為每個區域翻譯,因為奧地利和瑞士等國使用的德語沒有太大 的區別。所以可以使用中立的區域性來本地化應用程序,而不需要使用特定的區域性。 不變的區域性獨立于真正的區域性。在文件中存儲格式化的數字或日期,或通過網絡把它們發 送到服務器上時,最好使用獨立于任何用戶設置的區域性。 下圖顯示了區域性類型的相互關系。 CurrentCulture和CurrentUICulture設置區域性時,必須區分用戶界面的區域性和數字及日期格式的區域性。區域性與線程相關, 并且通過這兩種區域性類型,就可以把兩種區域性設置應用于線程。Thread 類提供了CurrentCulture 和CurrentUICulture 屬性。CurrentCulture 屬性用于設置與格式化和排序選項一起使用的區域性,而 CurrentUICulture 屬性用于設置用戶界面的語言。 使用 Windows 控制面板中的“區域和語言”選項,就可以改變CurrentCulture 的默認設置,如 下圖 所示。使用這個配置,還可以改變區域性的默認數字、時間和日期格式。 CurrentUICulture 屬性不依賴于這個配置,而依賴于操作系統的語言。這有一個例外:如果 Windows 7、Windows Vista 或Windows XP 安裝了多語言用戶界面(Multi-language User Interface, MUI),就可以用區域配置改變用戶界面的語言,這會影響CurrentUICulture 屬性。 這些設置都使用默認值,在許多情況下,不需要改變默認值。如果需要改變區域性,只需把線 程的兩個區域性改為Spanish 區域性,如下面的代碼段所示:
前面已學習了區域性的設置,下面討論CurrentCulture 設置對數字和日期格式的影響。 數字格式System 名稱空間中的數字結構Int16、Int32 和Int64 等都有一個重載的ToString()方法。這個方 法可以根據地域創建不同的數字表示法。對于Int32 結構,ToString()方法有下述4 個重載版本:
不帶參數的ToString()方法返回一個沒有格式化選項的字符串,也可以給ToString()方法傳遞一 個字符串和一個實現IFormatProvider 接口的類。 該字符串指定表示法的格式。而這個格式可以是標準數字格式化字符串或者圖形數字格式化字 符串。對于標準數字格式化,字符串是預定義的,其中C 表示貨幣符號,D 表示輸出為小數,E 表 示輸出用科學計數法表示,F 表示定點輸出,G 表示一般輸出,N 表示輸出為數字,X 表示輸出為 十六進制數。對于圖形數字格式化字符串,可以指定位數、節和組分隔符、百分號等。圖形數字格 式字符串###, ###表示兩個3 位數塊被一個組分隔符分開。 IFormatProvider 接口由NumberFormatInfo、DateTimeFormatInfo 和CultureInfo 類實現。這個接 口定義了GetFormat()方法,它返回一個格式對象。 NumberFormatInfo 類可以為數字定義自定義格式。使用NumberFormatInfo 類的默認構造函數, 可以創建獨立于區域性的對象或不變的對象。使用這個類的屬性,可以改變所有格式選項,如正號、 百分號、數字組分隔符和貨幣符號等。從靜態屬性InvariantInfo 返回一個與區域性無關的只讀 NumberFormatInfo 對象。NumberFormatInfo 對象的格式化值取決于當前線程的CultureInfo 類,該線 程從靜態屬性CurrentInfo 返回。 下一個示例使用一個簡單的控制臺項目。在這段代碼中,第一個示例顯示了在當前線程的區域 性格式中所顯示的數字(這里是English-US,是操作系統的設置)。第二個示例使用了帶有 IFormatProvider 參數的ToString()方法。CultureInfo 類實現IFormatProvider 接口,所以創建一個使用 法國區域性的CultureInfo 對象。第3 個示例改變了當前線程的區域性。使用Thread 實例的 CurrentCulture 屬性,把區域性改為德國區域性:
結果如下所示。可以把這個結果與前面列舉的美國、英國、法國和德國區域性的結果進行比較。
對于日期,也提供了與數字相同的支持。DateTime 結構有一些把日期轉換為字符串的方法。公 共實例的ToLongDateString()、ToLongTimeString()、ToShortDateString()和ToShortTimeString()方法都使用當前區域性來創建字符串表示法。使用ToString()方法,可以指定另一種區域性:
使用ToString()方法的字符串參數,可以指定預定義格式字符或自定義格式字符串,把日期轉換 為字符串。DateTimeFormatInfo 類指定了可能的值。DateTimeFormatInfo 類指定的格式字符串有不同 的含義。例如,D 表示長日期格式,d 表示短日期格式, ddd 表示星期的縮寫,dddd 表示星期的全 稱,yyyy 表示年份,T 表示長時間格式,t 表示短時間格式。使用IFormatProvider 參數可以指定區 域性。使用不帶IFormatProvider 參數的重載方法,表示所使用的是當前線程的區域性:
這個示例程序的結果說明了使用線程的當前區域性的ToLongDateString()方法,其中給ToString() 方法傳遞一個CultureInfo 實例,則顯示其法國版本,把線程的CurrentCulture 屬性改為es-ES,則顯 示其西班牙版本,如下所示。
使用區域性為了全面介紹區域性,下面使用一個WPF 應用程序示例,該應用程序列出所有的區域性,描 述區域性屬性的不同特征。下圖 顯示了該應用程序在Visual Studio 2010 WPF 設計器中的用戶界 面。 在應用程序的初始化階段,所有可用的區域性都添加到應用程序左邊的樹形視圖控件中。這個初 始化在AddCulturesToTree()方法中進行,該方法在Window類CultureDemoWindow的構造函數中調用:
在AddCulturesToTree()方法中,從通過靜態方法CultureInfo.GetCultures()中獲取所有區域性。給 這個方法傳遞CultureTypes.AllCultures,就會返回所有可用區域性的未排序數組。該數組用一個 Lambda 表達式排序,這個Lambda 表達式要傳遞給Array.Sort()方法的第二個參數的Comparison 委 托。在foreach 循環中,把每個區域性添加到樹形視圖中。為每種區域性創建一個TreeViewItem 對 象,因為WPF 的TreeView 類使用TreeViewItem 對象來顯示。將TreeViewItem 對象的Tag 屬性設置 為CultureInfo 對象,以便以后訪問這個樹型視圖中的CultureInfo 對象。 TreeViewItem 對象添加到樹中的什么地方取決于區域性類型。如果區域性沒有父區域性,它就 會添加到樹的根節點上。要查找父區域性,必須把所有區域性保存到一個字典中。相關內容參見前 面章節,其中第10 章介紹了字典,第8 章介紹了Lambda 表達式。
在用戶選擇樹中的一個節點時,就會調用TreeView 類的SelectedItemChanged 事件的處理程序。 在這里,這個處理程序在TreeCultures_SelectedItemChanged()方法中實現。在這個方法中,先調用 ClearTextFields()方法清除所有字段,再選擇TreeViewItem 對象的Tag 屬性,從樹中獲取CultureInfo 對象。接著使用CultureInfo 對象的屬性Name、NativeName 和EnglishName 設置一些文本字段。如果 CultureInfo 對象是一個可以使用IsNeutralCulture 屬性進行查詢的中立區域性,就設置相應的復選框。
然后獲取區域性的日歷信息。CultureInfo 類的Calendar 屬性返回特定區域性的默認Calendar 對 象。因為Calendar 類沒有對應的名稱屬性,所以需要使用基類的ToString()方法獲取類的名稱,并刪 除要在文本字段textCalendar 中顯示的這個字符串的名稱空間。 因為一種區域性可能支持多種日歷,所以OptionalCalendars 屬性返回額外支持的Calendar 對象 數組。這些可選的日歷顯示在列表框listCalendars 中。派生自Calendar 的GregorianCalendar 類還有 一個CalendarType 屬性,它列出了Gregorian 日歷的類型。這個類型可以是GregorianCalendarTypes 枚舉的一個值:Arabic、MiddleEastFrench、TransliteratedFrench、USEnglish 或Localized,這取決于 區域性。使用Gregorian 日歷,類型還可以顯示在列表框中。
接著,在if 語句中使用“!ci.IsNeutralCulture”,以檢查區域性是否為特定區域性(不是中立區域 性)。使用ShowSamples()方法顯示數字和日期示例。這個方法將在下一段代碼中實現。使用 ShowRegionInformation()方法顯示區域的一些信息。對于不變的區域性,只能顯示數字和日期示例, 不能顯示區域信息。因為不變的文件與實際的語言無關,所以它與區域也無關。
為了顯示一些本地化的數字和日期,把CultureInfo 類型的選中對象傳遞給ToString()方法的 IFormatProvider 參數。
為了顯示與RegionInfo 對象相關的信息,通過在ShowRegionInformation()方法中傳遞選中的區域性標識符,構造一個RegionInfo 對象,然后訪問DisplayName、CurrencySymbol、ISOCurrencySymbol 和IsMetric 屬性,以顯示這些信息。
啟動應用程序,在樹形視圖中就會看到所有的區域性,選擇一個區域性后,就會列出該區域性 的特征。 排序排序字符串取決于區域性。一些區域性有不同的排列順序。例如在芬蘭,字符V 和W 就是相 同的。在默認情況下,為排序而比較字符串的算法要使用與區分區域性的排序方式,其中排序依賴 于區域性。 為了說明芬蘭的排序方式,下面的代碼創建一個控制臺應用程序小示例,其中對數組中尚未排 序的美國州名進行排序。因為我們將使用System.Collections.Generic 、System.Threading 和 System.Globalization 名稱空間中的類,所以必須聲明這些名稱空間。下面的DisplayNames()方法用 于在控制臺上顯示數組或集合中的所有元素:
在Main()方法中,在創建了包含一些美國州名的數組后,就把線程的CurrentCulture 屬性設置 為Finnish 區域性,這樣,下面的Array.Sort()方法就使用芬蘭的排列順序。調用DisplayNames()方法 在控制臺上顯示所有的州名:
在以芬蘭排列順序第一次顯示美國州名后,數組將再次排序。如果希望排序獨立于用戶的區域 性,就可以使用不變的區域性。在已排序的數組要發送到服務器上,或存儲到某個地方時,就可以 采用這種方式。
這個程序的輸出顯示了用Finnish 區域性進行排岸的結果和獨立于區域性的排序結果。在使用獨 立于文件的排序方式時,Virginia 排在Washington 的前面。用Finnish 區域性進行排序時,Virginia 排在Washington 的后面。
如果對集合進行的排序應獨立于區域性,該集合就必須用不變的區域性進行排 序。在把排序結果發送給服務器或存儲在文件中時,這種方法尤其有效。 除了依賴地域的格式化和測量系統之外,文本和圖片也可能因區域性的不同而不同。此時就需要使用資源。 閱讀原文:原文鏈接 該文章在 2025/3/24 13:20:49 編輯過 |
關鍵字查詢
相關文章
正在查詢... |