目 錄
第十三章 中英文版本切換設(shè)計(jì)... 2
13.1 不用自帶的資源文件的理由... 2
13.2 配置文件... 2
13.3 語言管理類... 3
13.4 應(yīng)用管理類... 12
13.5 小結(jié)... 12
可以利用resx資源文件進(jìn)行多語言設(shè)計(jì),resx文件本身是kv類型的資源文件,設(shè)計(jì)好資源文件后,啟動(dòng)軟件時(shí)可以通過CurrentCulture屬性設(shè)置要顯示的語言。實(shí)現(xiàn)代碼如下:
//設(shè)置成英文版本
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-us");
但是,軟件涉及到多線程、線程池、異步等應(yīng)用的時(shí)候,當(dāng)前線程設(shè)置了英文版本,其他線程還是默認(rèn)的語言文化,例如:主線程設(shè)置了en-US,但是新建線程和其他已經(jīng)存在的線程還是zh-CN,如果各部分UI不在同一線程更新的話,語言文化的設(shè)置是不一樣的,所以沒有辦法實(shí)現(xiàn)統(tǒng)一的語言顯示。
那么,可不可以通過進(jìn)程獲得所有線程信息,統(tǒng)一進(jìn)行設(shè)置語言文化信息呢,的確是一個(gè)很好的想法。但是,通過實(shí)踐證明這是行不能的,可能造反軟件異常退出。為什么會(huì)出現(xiàn)這個(gè)現(xiàn)象呢?我猜想,一個(gè)進(jìn)程中不僅包括自定義的線程,還存在系統(tǒng)級(jí)的線程,這樣操作是一件危險(xiǎn)的事。
難道就沒有辦法實(shí)現(xiàn)了嗎?人不可能被尿憋死。在.NET 4.5中就簡單多了,直接使用System.Globalization命名空間內(nèi)CultureInfo類型的 DefaultThreadCurrentCulture和DefaultThreadCurrentUICulture屬性。設(shè)置好后,每一個(gè)新線程的 CurrentUICulture和CurrentCulture屬性都會(huì)和這個(gè)值保持一致的。CultureInfo類具體怎么實(shí)現(xiàn)的,還沒有研究過。
為了兼容XP操作系統(tǒng),還在使用.NET4.0的框架。相信也可以實(shí)現(xiàn)CultureInfo類的功能,但是不如自己設(shè)計(jì)一套語言版本方案更直接、更省時(shí)間。有時(shí)間的情況下可以研究一下CultureInfo類的實(shí)現(xiàn)。
先設(shè)計(jì)語言配置文件,文件格式采用xml,存儲(chǔ)方式采用KV的方式,文件命名可以自定義,例如:cn.xml、en.xml。如下圖:
Key的定義有兩種方式,第一種:窗體命名.控件命名,可以對窗體的控件統(tǒng)一改變顯示的語言信息。第二種:直接定義關(guān)鍵字,可以對提示信息、狀態(tài)信息等單獨(dú)詞條改變顯示的語言信息。Value就是最終要顯示語言的具體內(nèi)容,完全自定義。
[Serializable]public class CultureItem{ /// <summary> /// 控件的級(jí)聯(lián)ID,中間用"."分隔 /// </summary> [XmlAttribute] public string Key { set; get; } /// <summary> /// 中文或英文描述 /// </summary> [XmlAttribute] public string Value { set; get; }}
public class CultureMananger{ PRivate static Dictionary<string, string> _dic = new Dictionary<string, string>(); private static string _cnPath = application.StartupPath + "http://SuperIO//Language//cn.xml"; private static string _enPath = Application.StartupPath + "http://SuperIO//Language//en.xml"; private static object SyncObject = new object(); /// <summary> /// 加載語言文件到緩存中 /// </summary> public static void LoadCulture() { lock (SyncObject) { if (IsLanguage) { try { _dic.Clear(); string path = String.Empty; if (Language == CultureLanguage.Chinese) { path = _cnPath; } else if (Language == CultureLanguage.English) { path = _enPath; } if (File.Exists(path)) { List<CultureItem> itemList =SerializeOperation.SerializeOperation.GetSerialize<List<CultureItem>>(path); foreach (CultureItem item in itemList) { _dic.Add(item.Key, item.Value); } } } catch (Exception ex) { GeneralLog.WriteLog(ex); } } } } /// <summary> /// 清除緩存中的語言信息 /// </summary> public static void ClearCache() { lock (SyncObject) { _dic.Clear(); } } /// <summary> /// 設(shè)置和獲得語言類型屬性 /// </summary> public static CultureLanguage Language { set { if (GlobalProperty.GetInstance().Language != value) { GlobalProperty.GetInstance().Language = value; GlobalProperty.GetInstance().Save(); LoadCulture(); } } get { return GlobalProperty.GetInstance().Language; } } /// <summary> /// 獲得詞條對應(yīng)的描述信息 /// </summary> /// <param name="formName">窗體名稱</param> /// <param name="field">詞條字段</param> /// <returns>對應(yīng)的描述信息</returns> public static string GetString(string formName, string field) { return GetString(String.Format("{0}.{1}", formName, field)); } /// <summary> /// 獲得詞條對應(yīng)的描述信息 /// </summary> /// <param name="key">字段的關(guān)鍵字</param> /// <returns></returns> public static string GetString(string key) { lock (SyncObject) { if (IsLanguage) { string val = String.Empty; if (_dic.ContainsKey(key)) { _dic.TryGetValue(key, out val); } return val; } else { return String.Empty; } } } /// <summary> /// 應(yīng)用窗體,改變語言顯示 /// </summary> /// <param name="frm"></param> public static void ApplyResourcesForm(Form frm) { if (IsLanguage) { string frmText = GetString(frm.Name); if (!String.IsNullOrEmpty(frmText)) { frm.Text = frmText; } ApplyControls(frm.Name, frm.Controls); } } /// <summary> /// 應(yīng)用BarManager工具具,改變語言顯示 /// </summary> /// <param name="name"></param> /// <param name="bar"></param> public static void AppResourceBarItem(string name, BarManager bar) { if (IsLanguage) { string key = String.Empty; foreach (BarItem item in bar.Items) { key = String.Format("{0}.{1}", name, item.Name); string val = GetString(key); if (!String.IsNullOrEmpty(val)) { item.Caption = val; } } } } /// <summary> /// 應(yīng)用控件,改變語言顯示 /// /summary> /// <param name="name"></param> /// <param name="ctrls"></param> public static void ApplyControls(string name, Control.ControlCollection ctrls) { if (IsLanguage) { foreach (Control ctrl in ctrls) { if (ctrl is MenuStrip) //MenuStrip StatusStrip { ApplyMenuStrip(name, (MenuStrip) ctrl); } else if (ctrl is StatusStrip) { ApplyStatusStrip(name, (StatusStrip) ctrl); } else if (ctrl is ListView) { ApplyListView(name, (ListView) ctrl); } else { ApplyControls(name, ctrl); } if (ctrl.HasChildren) { ApplyControls(name, ctrl.Controls); } } } } internal static bool IsLanguage { get { if (File.Exists(_cnPath) && File.Exists(_enPath)) { return true; } else { return false; } } } private static void ApplyControls(string name, Control ctrl) { string key = String.Format("{0}.{1}", name, ctrl.Name); string text = GetString(key); if (!String.IsNullOrEmpty(text)) { ctrl.Text = text; } } private static void ApplyMenuStrip(string name, MenuStrip menu) { foreach (ToolStripMenuItem item in menu.Items) { ApplyMenuItem(name, item); } } private static void ApplyMenuItem(string name, ToolStripMenuItem item) { string key = String.Format("{0}.{1}", name, item.Name); string text = GetString(key); if (!String.IsNullOrEmpty(text)) { item.Text = text; } if (item.DropDownItems.Count > 0) { foreach (ToolStripMenuItem subItem in item.DropDownItems) { ApplyMenuItem(name, subItem); } } } private static void ApplyStatusStrip(string name, StatusStrip status) { string key = String.Empty; foreach (ToolStripItem item in status.Items) { key = String.Format("{0}.{1}", name, item.Name); string val= GetString(key); if (!String.IsNullOrEmpty(val)) { item.Text = val; } } } private static void ApplyListView(string name, ListView lv) { string key = String.Empty; foreach (ColumnHeader header in lv.Columns) { key = String.Format("{0}.{1}", name, header.Tag == null ? "" : header.Tag.ToString()); string val = GetString(key); if (!String.IsNullOrEmpty(val)) { header.Text = val; } } }}
在軟件啟動(dòng)時(shí)可以使用CultureMananger管理類,具體應(yīng)用代碼如下:
CultureMananger.LoadCulture();CultureMananger.ApplyControls("MainForm",this.Controls);string state=CultureMananger.GetString("State.Normal");
這是一個(gè)小的工具組件,具有一定的通用性。
作者:唯笑志在
Email:504547114@QQ.com
QQ:504547114
.NET開發(fā)技術(shù)聯(lián)盟:54256083
文檔下載:http://pan.baidu.com/s/1pJ7lZWf
官方網(wǎng)址:http://www.bmpj.net
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注