/******************************************************************************************
*【Author】:itwalker
*【Email】:itwalker@hotmail.com
*【Date】:2005年7月3日
*【Notice】:
*1、本文為原創(chuàng)技術文章,首發(fā)博客園(www.cnblogs.com),轉載和引用請注明作者及出處。
*2、本文必須全文轉載和引用,任何組織和個人未授權不能修改任何內容,并且未授權不可用于商業(yè)。
*3、本聲明為文章一部分,轉載和引用必須包括在原文中。
******************************************************************************************/
最近開發(fā)工作涉及到.net程序的多語言支持,完成之后,發(fā)現(xiàn)這項工作其實分兩部分,第一部分是關鍵,實現(xiàn)多語言的幾個對象和方法,第二部分是體力活,把程序中所有涉及到有文字表述的地方——title、label、text、message依次在資源文件中對應輸入準備實現(xiàn)的語種語言。而實際上,即使是件體力活,你還是會發(fā)現(xiàn),實現(xiàn)程序的多語言支持,是一件比較有趣的工作。
從.net的多語言模型來看,多語言的關鍵是資源文件和.net提供的資源管理類ResourceManager(當然,實現(xiàn)多語言不會只用到這一個類,還需要其他幾個類),不同的語種對應一個資源文件,資源文件是多語言的載體,ResourceManager類是實現(xiàn)多語言的調度。沒有多語言支持的程序,所有程序中的文字信息在編譯的時候生成在程序集中,提供多語言支持的程序,最終將生成一個主程序集和對應的多語言附屬程序集,用反編工具查看附屬程序集,全部是資源文件中的內容。MSDN的資料也講:資源文件從Visual Studio XML 格式 (.resX) 編譯為中間二進制格式 (.resources),然后將該二進制文件嵌入附屬程序集中(ms-help://MS.MSDNQTR.2003FEB.2052/vbcon/html/vbconInternationalizingApplications.htm)。原來如此。
因為是總結性的備忘文章,下面記錄的是實際中參照MSDN的相關文章遇到問題的地方。
一、web應用的多語言:
ms-help://MS.MSDNQTR.2003FEB.2052/vbcon/html/vbwlkWalkthroughLocalizingWebForms.htm
web界面實現(xiàn)多語言所有的詳細過程都在MSDN這篇文章中。不過,有兩點不太符合實際工作,文章面向的是一個只有一個頁面的樣例工程,而我需要處理的是二、三十個web頁面,按照文章所述方法一個頁面一個頁面去設置多語言區(qū)域,工作量過大,如果是成百上千個頁面就崩潰了。我需要有一個地方來統(tǒng)一設置多語言的區(qū)域信息,然后具體頁面只需關心在什么地方替換成對應語言即可。另外,樣例的多語言支持,是根據(jù)客戶端瀏覽器的語言區(qū)域信息來決定顯示語言,而我們要實現(xiàn)的是根據(jù)webv.config的設置來決定顯示語言。比如,即使是中文瀏覽器,但如果指定的是英文版,顯示的就應該是英文。
對于第一個問題,很自然的,想到Global.asax.cs中的Application_BeginRequest事件方法。于是,在Application_BeginRequest事件方法中加入這樣的代碼:
DefaultCultrue,就是在web.config文件中配置版本的項。
然后是在頁面中的操作,這里遇到些周折。
從上面的樣例代碼中參數(shù)typeof(WebForm1).Assembly來看,似乎沒有什么問題,在每個頁面Page_Load 中拷貝上這句,修改成對應頁面名稱即可,但是能不能用一個通用的對象來代替這個Assembly對象而不用指定頁面呢?經(jīng)過幾次周折,最后發(fā)現(xiàn)可以這樣實現(xiàn):
第一部分就這樣搞定,其余的就是第二部分的體力活了,不表。
二、windows應用的多語言
ms-help://MS.MSDNQTR.2003FEB.2052/cssample/html/vcsamMultilingualFormSample.htm
這里的樣例和文章基本上只是起了一個參考作用,因為跟我最終要實現(xiàn)的有所不同。
windows應用的多語言支持稍有不同,體現(xiàn)在兩方面,一個是沒有可保存設置的配置文件(當然自己加上也不是什么問題),另一個就是用實例化通用Assembly對象也有不同。
對第一個問題,經(jīng)過測試,發(fā)現(xiàn)應用程序能自動識別當前操作系統(tǒng)語言版本調用相應語言,如果使用配置文件需要用戶自己設定,這個不同于web應用,管理員設置一次即可,意義不大,于是決定不作處理,讓應用程序自動識別操作系統(tǒng)語言版本調用相應語言,需要解決的就是第二問題了。
其實,第二個問題的發(fā)現(xiàn)和解決都在第一個問題中,使用web頁面上的方法來取用當前窗體類型出錯,單步跟蹤調試,發(fā)現(xiàn)用“this.GetType().BaseType”取到的類型名稱是“System.Windows.Forms.Form”,顯然不對,用監(jiān)視查看了一下代碼“this.GetType()”獲得的對象,居然FullName一項中正是需要的內容,修改了一下代碼:
繼續(xù)體力活,結束之后用虛擬機啟動英文版的windows,運行修改之后的windows應用,結果跟預期相符。
三、Office COM外接程序的多語言
這個雖然MSDN上沒有相關文章,不過,道理是一樣的,跟上面windows應用的多語言不同的地方就是,上面windows應用的多語言需要在每個窗體中實現(xiàn),而office COM有窗體的地方實現(xiàn)一樣,沒有窗體而有message的地方,就針對類進行處理,在類的構造函數(shù)中實例化ResourceManager對象。
另外,區(qū)域性名稱遵循 RFC 1766 標準,詳細的名稱、地區(qū)對應表在CultrueInfo類中可以找到。要注意的是,資源文件的命名和web.config中的配置要使用特定區(qū)域名稱而不能使用非特定區(qū)域名稱,比如,英文,應該指明使用美國英語“en-us”還是英國英語“en-GB”,而不能僅僅使用“en”。
最后,上述三類.net程序的多語言支持工作完成用了一個工作周時間,體力活的時間四天半,第一部分只用了半天……古人說,得鳥者,羅之一目,一目之羅,不可得鳥。應該是了。