读书人

c#winform:开发多语言应用程序!解决方

发布时间: 2012-04-14 17:14:21 作者: rapoo

c#winform:开发多语言应用程序!!
问题是:在窗体上添加一个语言menu,有几个选项:english,Chinese(simplied),German,Japanes等选项,当选择其中一项时,程序的语言就显示该语言。
程序默认语言是english.
例如:程序的登陆界面上有几个label,分别为UserName,password,login,servername。当选择Chinese(simplied)选项时,这几个label应显示为:用户名,密码,登录,服务器名。

大概就是这个意思,很多网站都提供多语言选项的。
因本人是初学者,有些东西不明白,所以希望大家能提供一个具体可行的方法。
谢谢各位高手!!!



[解决办法]
动态加载资源文件
[解决办法]
一般情况下都是用资源文件做,不过不推荐使用.
最好是做多个XML文件,有几种语言就做几个XML文件. 用来保存控件名,以及控件的内容,
例如:英文XML文件
<form Name = 'Login'>
<Control name = 'BtnSave'>
Save
</Control>
</form>
对应的中文文件就是
<form Name = 'Login'>
<Control name = 'BtnSave'>
保存
</Control>
</form>

还要用个地方来保存默认语言.


每次启动一个窗体的时候首先识别默认语言,然后根据默认语言遍历Xml文件.
[解决办法]
把所有字段存放在一个表中,程序运行时从这表中读取相应的语言的字段。
如:建一个mFieldName表,用Form的名字和FieldName做关键字,再加几个english,Chinese(simplied),German,Japanes等字段,当然在修改或新加窗体的时候维护这个表.
然后在程序运行时根据不同的选项读取不同的字段(english,Chinese(simplied),German,Japanes)。
[解决办法]

C# code
<?xml version="1.0" encoding="utf-8"?> <Text>   <TAG key="0001" CHS="国际贸易-供应链系统" JP="" KR="?????????" EN="" />   <TAG key="0002" CHS="中文" JP="" KR="????" EN="" />   <TAG key="0003" CHS="韩文" JP="" KR="????" EN="" />   <TAG key="0004" CHS="国际贸易" JP="" KR="" EN="" />   <TAG key="0005" CHS="供应链系统" JP="" KR="" EN="" />   <TAG key="00001" CHS="添加药品类别-" JP="" KR="??????" EN="" /> </Text> <!--这个写在在Text.config里面,假设一个Label吧你起名字就的LG_lblName 其余的控件都的起这样的前面加上LG_XX 然后在aspx里面的 <form>  <asp:Panel ID="LG_Panel" runat="server"  Width="100%"> <table> <tr> <td>ddd </td> </tr> </table> </asp:Panel > </form>这些都是必须的。然后调用的时候也就是我 给你的那个类在上面 CS里面这样调用 Language.ChangeControlsText(LG_Panel); 支持多国语言。忘了起名字的时候假设国际贸易-供应链系统叫这个名字吧 ,那这个Label吧你起名字就的叫LG_0001必须和 Text.Config里面的 对起来 <TAG  key="0001"  CHS="国际贸易-供应链系统"  JP=""   KR="?????????"  EN=""  /> -->
[解决办法]
探讨
一般情况下都是用资源文件做,不过不推荐使用.
最好是做多个XML文件,有几种语言就做几个XML文件. 用来保存控件名,以及控件的内容,
例如:英文XML文件
<form Name = 'Login'>
<Control name = 'BtnSave'>
Save
</Control>
</form>
对应的中文文件就是
<form Name = 'Login'>
<Control name = 'BtnSave'>
保存
</Control>
</form>

还要用个地方来保存默认语言.


每次启动一个窗体的时候首先识别…

[解决办法]
C# code
/* * //ArrayList 和 StringCollection 类以及 List 泛型类通过元素的从零开始的索引提供对元素的访问。//Hashtable、SortedList、ListDictionary 和 StringDictionary 类以及 Dictionary 和 SortedDictionary 泛型类通过元素的键提供对元素的访问。//NameObjectCollectionBase 和 NameValueCollection 类以及 KeyedCollection 和 SortedList 泛型类通过其元素的从零开始的索引或者通过其元素的键提供对元素的访问。 *  *  * **************** * CultureInfo 类 * * **************** 区域性/语言名称  区域性标识符  区域性  ""(空字符串)  0x007F  固定区域性  af  0x0036  南非荷兰语  af-ZA  0x0436  南非荷兰语(南非) sq  0x001C  阿尔巴尼亚语  sq-AL  0x041C  阿尔巴尼亚语(阿尔巴尼亚)  ar  0x0001  阿拉伯语  ar-DZ  0x1401  阿拉伯语(阿尔及利亚)  ar-BH  0x3C01  阿拉伯语(巴林)  ar-EG  0x0C01  阿拉伯语(埃及)  ar-IQ  0x0801  阿拉伯语(伊拉克)  ar-JO  0x2C01  阿拉伯语(约旦)  ar-KW  0x3401  阿拉伯语(科威特)  ar-LB  0x3001  阿拉伯语(黎巴嫩)  ar-LY  0x1001  阿拉伯语(利比亚)  ar-MA  0x1801  阿拉伯语(摩洛哥)  ar-OM  0x2001  阿拉伯语(阿曼)  ar-QA  0x4001  阿拉伯语(卡塔尔)  ar-SA  0x0401  阿拉伯语(沙特阿拉伯)  ar-SY  0x2801  阿拉伯语(叙利亚)  ar-TN  0x1C01  阿拉伯语(突尼斯)  ar-AE  0x3801  阿拉伯语(阿联酋)  ar-YE  0x2401  阿拉伯语(也门)  hy  0x002B  亚美尼亚语  hy-AM  0x042B  亚美尼亚语(亚美尼亚)  az  0x002C  阿泽里语  az-Cyrl-AZ  0x082C  阿泽里语(阿塞拜疆,西里尔语)  az-Latn-AZ  0x042C  阿泽里语(阿塞拜疆,拉丁语)  eu  0x002D  巴斯克语  eu-ES  0x042D  巴斯克语(巴斯克地区)  be  0x0023  白俄罗斯语  be-BY  0x0423  白俄罗斯语(白俄罗斯)  bg  0x0002  保加利亚语  bg-BG  0x0402  保加利亚语(保加利亚)  ca  0x0003  加泰罗尼亚语  ca-ES  0x0403  加泰罗尼亚语(加泰罗尼亚地区)  zh-HK  0x0C04  中文(香港特别行政区,中国)  zh-MO  0x1404  中文(澳门特别行政区)  zh-CN  0x0804  中文(中国)  zh-Hans  0x0004  中文(简体)  zh-SG  0x1004  中文(新加坡)  zh-TW  0x0404  中文(台湾)  zh-Hant  0x7C04  中文(繁体)  hr  0x001A  克罗地亚语  hr-HR  0x041A  克罗地亚语(克罗地亚)  cs  0x0005  捷克语  cs-CZ  0x0405  捷克语(捷克共和国)  da  0x0006  丹麦语  da-DK  0x0406  丹麦语(丹麦)  dv  0x0065  迪维希语  dv-MV  0x0465  迪维希语(马尔代夫)  nl  0x0013  荷兰语  nl-BE  0x0813  荷兰语(比利时)  nl-NL  0x0413  荷兰语(荷兰)  en  0x0009  英语  en-AU  0x0C09  英语(澳大利亚)  en-BZ  0x2809  英语(伯利兹)  en-CA  0x1009  英语(加拿大)  en-029  0x2409  英语(加勒比)  en-IE  0x1809  英语(爱尔兰)  en-JM  0x2009  英语(牙买加)  en-NZ  0x1409  英语(新西兰)  en-PH  0x3409  英语(菲律宾)  en-ZA  0x1C09  英语(南非)  en-TT  0x2C09  英语(特立尼达和多巴哥)  en-GB  0x0809  英语(英国)  en-US  0x0409  英语(美国)  en-ZW  0x3009  英语(津巴布韦)  et  0x0025  爱沙尼亚语  et-EE  0x0425  爱沙尼亚语(爱沙尼亚)  fo  0x0038  法罗语  fo-FO  0x0438  法罗语(法罗群岛)  fa  0x0029  波斯语  fa-IR  0x0429  波斯语(伊朗)  fi  0x000B  芬兰语  fi-FI  0x040B  芬兰语(芬兰)  fr  0x000C  法语  fr-BE  0x080C  法语(比利时)  fr-CA  0x0C0C  法语(加拿大)  fr-FR  0x040C  法语(法国)  fr-LU  0x140C  法语(卢森堡)  fr-MC  0x180C  法语(摩纳哥)  fr-CH  0x100C  法语(瑞士)  gl  0x0056  加利西亚语  gl-ES  0x0456  加利西亚语(西班牙)  ka  0x0037  格鲁吉亚语  ka-GE  0x0437  格鲁吉亚语(格鲁吉亚)  de  0x0007  德语  de-AT  0x0C07  德语(奥地利)  de-DE  0x0407  德语(德国)  de-LI  0x1407  德语(列支敦士登)  de-LU  0x1007  德语(卢森堡)  de-CH  0x0807  德语(瑞士)  el  0x0008  希腊语  el-GR  0x0408  希腊语(希腊)  gu  0x0047  古吉拉特语  gu-IN  0x0447  古吉拉特语(印度)  he  0x000D  希伯来语  he-IL  0x040D  希伯来语(以色列)  hi  0x0039  印地语  hi-IN  0x0439  印地语(印度)  hu  0x000E  匈牙利语  hu-HU  0x040E  匈牙利语(匈牙利)  is  0x000F  冰岛语  is-IS  0x040F  冰岛语(冰岛)  id  0x0021  印度尼西亚语  id-ID  0x0421  印度尼西亚语(印度尼西亚)  it  0x0010  意大利语  it-IT  0x0410  意大利语(意大利)  it-CH  0x0810  意大利语(瑞士)  ja  0x0011  日语  ja-JP  0x0411  日语(日本)  kn  0x004B  卡纳达语  kn-IN  0x044B  卡纳达语(印度)  kk  0x003F  哈萨克语  kk-KZ  0x043F  哈萨克语(哈萨克斯坦)  kok  0x0057  贡根语  kok-IN  0x0457  贡根语(印度)  ko  0x0012  朝鲜语  ko-KR  0x0412  朝鲜语(韩国)  ky  0x0040  吉尔吉斯语  ky-KG  0x0440  吉尔吉斯语(吉尔吉斯坦)  lv  0x0026  拉脱维亚语  lv-LV  0x0426  拉脱维亚语(拉脱维亚)  lt  0x0027  立陶宛语  lt-LT  0x0427  立陶宛语(立陶宛)  mk  0x002F  马其顿语  mk-MK  0x042F  马其顿语(马其顿,FYROM)  ms  0x003E  马来语  ms-BN  0x083E  马来语(文莱达鲁萨兰)  ms-MY  0x043E  马来语(马来西亚)  mr  0x004E  马拉地语  mr-IN  0x044E  马拉地语(印度)  mn  0x0050  蒙古语  mn-MN  0x0450  蒙古语(蒙古)  no  0x0014  挪威语  nb-NO  0x0414  挪威语(伯克梅尔,挪威)  nn-NO  0x0814  挪威语(尼诺斯克,挪威)  pl  0x0015  波兰语  pl-PL  0x0415  波兰语(波兰)  pt  0x0016  葡萄牙语  pt-BR  0x0416  葡萄牙语(巴西)  pt-PT  0x0816  葡萄牙语(葡萄牙)  pa  0x0046  旁遮普语  pa-IN  0x0446  旁遮普语(印度)  ro  0x0018  罗马尼亚语  ro-RO  0x0418  罗马尼亚语(罗马尼亚)  ru  0x0019  俄语  ru-RU  0x0419  俄语(俄罗斯)  sa  0x004F  梵语  sa-IN  0x044F  梵语(印度)  sr-Cyrl-CS  0x0C1A  塞尔维亚语(塞尔维亚,西里尔语)  sr-Latn-CS  0x081A  塞尔维亚语(塞尔维亚,拉丁语)  sk  0x001B  斯洛伐克语  sk-SK  0x041B  斯洛伐克语(斯洛伐克)  sl  0x0024  斯洛文尼亚语  sl-SI  0x0424  斯洛文尼亚语(斯洛文尼亚)  es  0x000A  西班牙语  es-AR  0x2C0A  西班牙语(阿根廷)  es-BO  0x400A  西班牙语(玻利维亚)  es-CL  0x340A  西班牙语(智利)  es-CO  0x240A  西班牙语(哥伦比亚)  es-CR  0x140A  西班牙语(哥斯达黎加)  es-DO  0x1C0A  西班牙语(多米尼加共和国) es-EC  0x300A  西班牙语(厄瓜多尔)  es-SV  0x440A  西班牙语(萨尔瓦多)  es-GT  0x100A  西班牙语(危地马拉)  es-HN  0x480A  西班牙语(洪都拉斯)  es-MX  0x080A  西班牙语(墨西哥)  es-NI  0x4C0A  西班牙语(尼加拉瓜)  es-PA  0x180A  西班牙语(巴拿马)  es-PY  0x3C0A  西班牙语(巴拉圭)  es-PE  0x280A  西班牙语(秘鲁)  es-PR  0x500A  西班牙语(波多黎各)  es-ES  0x0C0A  西班牙语(西班牙)  es-ES_tradnl 0x040A 西班牙语(西班牙,传统排序) es-UY  0x380A  西班牙语(乌拉圭)  es-VE  0x200A  西班牙语(委内瑞拉)  sw  0x0041  斯瓦希里语  sw-KE  0x0441  斯瓦希里语(肯尼亚)  sv  0x001D  瑞典语  sv-FI  0x081D  瑞典语(芬兰)  sv-SE  0x041D  瑞典语(瑞典)  syr  0x005A  叙利亚语  syr-SY  0x045A  叙利亚语(叙利亚)  ta  0x0049  泰米尔语  ta-IN  0x0449  泰米尔语(印度)  tt  0x0044  鞑靼语  tt-RU  0x0444  鞑靼语(俄罗斯)  te  0x004A  泰卢固语  te-IN  0x044A  泰卢固语(印度)  th  0x001E  泰语  th-TH  0x041E  泰语(泰国)  tr  0x001F  土耳其语  tr-TR  0x041F  土耳其语(土耳其)  uk  0x0022  乌克兰语  uk-UA  0x0422  乌克兰语(乌克兰)  ur  0x0020  乌尔都语  ur-PK  0x0420  乌尔都语(巴基斯坦)  uz  0x0043  乌兹别克语  uz-Cyrl-UZ  0x0843  乌兹别克语(乌兹别克斯坦,西里尔语)  uz-Latn-UZ  0x0443  乌兹别克语(乌兹别克斯坦,拉丁语)  vi  0x002A  越南语  vi-VN  0x042A  越南语(越南)    */ 


[解决办法]
观察着+工厂方法,定义事件委托的实现
楼主看懂了结贴给满分,兄弟们也帮忙测试下,是不是这样写合理!!!?

C# code
using System;using System.Collections.Generic;using System.Text;using System.Globalization;using System.IO;namespace LocalizableLanguage{    /// <summary>    /// 观察目标对象,窗体FORM作为观察者    /// </summary>    public class SubjectLanguageObserver    {        private CultureInfo thisCulture;//具体的观察目标        public CultureInfo ThisCulture        {            get { return thisCulture; }            set { thisCulture = value; }        }               /// <summary>        /// 定义一个Delegate,用来规范函数结构。        /// 在激发事件时,函数会传递观察目标对象LanguageObserverSubject--》thisCulture和读到的数据        /// </summary>        /// <param name="sender">LanguageObserverSubject</param>        /// <param name="e">CultureInfoEventArgs</param>        public delegate void CultureInfoEventHandler(Object sender, CultureInfoEventArgs e);        /// <summary>        /// 让观察者FORM注册delegate事件CultureInfoEventHandler        /// </summary>        public event CultureInfoEventHandler CultureInfoChanged;    //声明事件               protected virtual void OnCultureInfoChanged(CultureInfoEventArgs e)        {            if (CultureInfoChanged != null)//如果有对象注册            {                CultureInfoChanged(this, e);//调用所有注册对象的方法            }        }        /// <summary>        /// 触发具体的观察目标的状态改变,改变 CultureInfo即改变UI的语言        /// </summary>        public void CultureInfoChangeUILanguage()        {            CultureInfoEventArgs e = new CultureInfoEventArgs(thisCulture);            OnCultureInfoChanged(e);        }        public void CultureInfoChangeUILanguage(CultureInfo c)        {            thisCulture = c;            CultureInfoEventArgs e = new CultureInfoEventArgs(c);            OnCultureInfoChanged(e);        }        public void CultureInfoChangeUILanguage(int cl_id)        {            thisCulture = new CultureInfo(cl_id);            CultureInfoEventArgs e = new CultureInfoEventArgs(thisCulture);            OnCultureInfoChanged(e);        }        /// <summary>        /// 传递给Observer所感兴趣的信息        /// </summary>        public class CultureInfoEventArgs : EventArgs        {            private readonly CultureInfo culture;            private readonly ILocalizableLanguage langDictionary;            public CultureInfoEventArgs(CultureInfo thisCulture)            {                culture = thisCulture;                ill = LocalizableLanguageFactory.CreateLocalizableLanguage(thisCulture);                langDictionary =ill ;            }                    }        private static  ILocalizableLanguage ill;        public ILocalizableLanguage languageDictionary { get { return ill; } }        public SubjectLanguageObserver()        {            if (thisCulture == null)                thisCulture = System.Threading.Thread.CurrentThread.CurrentCulture;            ill = LocalizableLanguageFactory.CreateLocalizableLanguage(thisCulture);        }    }    public interface ILocalizableLanguage {        string  GetLocalizableLanguageByKey(string key);    }    internal abstract class AbstractLocalizableLanguage : ILocalizableLanguage {        public abstract string GetLocalizableLanguageByKey(string key);        public abstract IDictionary<string, string> LoadLanguageFile(string path);        private IDictionary<string, string> languageDictionary;        public IDictionary<string, string> LanguageDictionary        {            get { return languageDictionary; }            set { languageDictionary = value; }        }    }
[解决办法]
我的代码的思想是:
在窗体类中,窗体作为观察者,监视CultureInfo对象,
CultureInfo的改变,将激发界面语言的改变,
所以,在form类中建立观察者的基类,并注册事件,
CultureInfo的改变要使得ILocalizableLanguage 接口对象的改变,


而用工厂方法返回依据CultureInfo创建的不同的语言对象!
[解决办法]
一般可以用两种方式,
1.资源文件。
2.xml配置,程序启动时根据用户选择加载对应语言的xml。
[解决办法]
多语言支持实际上是两个问题:
1、字符串储存,这个有好多方法,可以用资源文件、Xml甚至普通文本文件都可以
2、怎么在程序中赋值,这才是麻烦的问题。一般都是在设计界面中给控件设定名称的,而设计界面中只能赋简单的字符串,显然不符合要求。而完全通过在程序中写代码赋值虽然可行,但是少数几个控件可以,成百上千个控件都要这样干就成问题了。我的想法是,在设计界面中设定名称的控件,通过递归遍历所有控件,根据ID或者其他可行的方式查找资源文件里的字符串,并赋值。而对于写代码赋值的,比如动态创建的控件名称、异常信息等等,直接改成从资源文件读取就可以。
具体实施起来可能不止这么简单,最近也需要实现全球化支持,等研究了再来讨论。

读书人网 >C#

热点推荐