问题是:在窗体上添加一个语言menu,有几个选项:english,Chinese(simplied),German,Japanes等选项,当选择其中一项时,程序的语言就显示该语言。
程序默认语言是english.
例如:程序的登陆界面上有几个label,分别为UserName,password,login,servername。当选择Chinese(simplied)选项时,这几个label应显示为:用户名,密码,登录,服务器名。大概就是这个意思,很多网站都提供多语言选项的。
因本人是初学者,有些东西不明白,所以希望大家能提供一个具体可行的方法。
谢谢各位高手!!!
程序默认语言是english.
例如:程序的登陆界面上有几个label,分别为UserName,password,login,servername。当选择Chinese(simplied)选项时,这几个label应显示为:用户名,密码,登录,服务器名。大概就是这个意思,很多网站都提供多语言选项的。
因本人是初学者,有些东西不明白,所以希望大家能提供一个具体可行的方法。
谢谢各位高手!!!
解决方案 »
- WPF OpenFileDialog这个对话框有人重写过吗
- 100分求Word分页转换Html页面的解决方案
- C#,WEBFORM,向EXCEL写数据出问题
- 绝对简单!C#链接MySql
- rdlc报表 XML 动态的产生
- 关于Socket通信的问题,求救,急...
- 一道作业题
- 高分!我要使用c# windows form 写一个类似于foxmail 的收发邮件系统,我想调用word的编辑器来发html邮件(或其他编辑器也行),有谁知道或做
- 请问:我的台式的是赛扬1.7 ,256做.net开发, 那我如果想买个笔记本用,该用什么配置的呢?(在线等,望版主保留此贴二天)谢谢!!!!
- 请CForce进来拿分
- 求最小生成树Prim()算法实现(用C#)
- c#winform:开发多语言应用程序---多国语言本地化与设计模式的思考----观察者模式+工厂模式!有请五裤衩以上的掌柜地主们发言
最好是做多个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)。
那没办法,你必须要进行翻译;你可以在app.config 里面进行设置,加载不同的资源文件
<?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="" /> -->
但是可以加密。呵呵。
/*
*
//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
越南语(越南)
*/这是资源文件反射后判断的基础
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
////""(空字符串) 0x007F 固定区域性
////en-GB 0x0809 英语(英国)
////en-US 0x0409 英语(美国)
////zh-HK 0x0C04 中文(香港特别行政区,中国)
////zh-MO 0x1404 中文(澳门特别行政区)
////zh-CN 0x0804 中文(中国)
////zh-Hans 0x0004 中文(简体)
////zh-SG 0x1004 中文(新加坡)
////zh-TW 0x0404 中文(台湾)
////zh-Hant 0x7C04 中文(繁体) System.Threading.Thread.CurrentThread.CurrentUICulture
= new System.Globalization.CultureInfo(0x007F);
FormStart fs = new FormStart();
if (fs.ShowDialog() == DialogResult.OK)
{
Application.Run(new FormMain());
}
else
Application.Exit();
}
}
{
public FormStart()
{
InitializeComponent();
FormatLanguageValues();
} private void buttonOK_Click(object sender, EventArgs e)
{
buttonOK.DialogResult = DialogResult.OK;
this.DialogResult = buttonOK.DialogResult;
}
ILocalizableLanguage ILL;
private void FormatLanguageValues()
{
ILL = new LanguageLocalization(System.Threading.Thread.CurrentThread.CurrentUICulture); this.label1.Text = ILL.GetLanguageValuesByName("FormStart.label1.Text");
this.label2.Text = ILL.GetLanguageValuesByName("FormStart.label2.Text");
this.checkBox1.Text = ILL.GetLanguageValuesByName("FormStart.checkBox1.Text");
this.buttonOK.Text = ILL.GetLanguageValuesByName("FormStart.buttonOK.Text");
}
}在上面界面实现中,我去读一个文本文件,如:default.lang[表示默认英语]/zh-Hans.lang[简体中文]
文本格式如下
FormStart.label1.Text = "label1";
FormStart.label2.Text = "label2";
FormStart.checkBox1.Text = "checkBox1";
FormStart.buttonOK.Text = "OK";
public interface ILocalizableLanguage
{
CultureInfo Culture { get;set;}
string GetLanguageValuesByName(string ControlName); } interface ILanguages { void TryGetValue(string ControlName, out string txt);}
public class LanguageLocalization :ILocalizableLanguage
{
public LanguageLocalization() { }
public LanguageLocalization(CultureInfo CurrentUI_Culture) {
CurrentUICulture = CurrentUI_Culture;
CurrentLanguage=InitializeLanguageLocalization(CurrentUICulture);
} private ILanguages InitializeLanguageLocalization(CultureInfo CurrentUICulture)
{
ILanguages currentLanguage;
switch (CurrentUICulture.LCID)
{
case 0x0004:
currentLanguage = new CHS();
break;
case 0x0804:
currentLanguage = new CHS();
break;
default:
currentLanguage = new Default();
break;
}
return currentLanguage;
}
CultureInfo CurrentUICulture;
ILanguages CurrentLanguage; #region ILocalizableLanguage 成员 public string GetLanguageValuesByName(string ControlName)
{
string txt=string .Empty ;
//LanguageValuesDictionary.TryGetValue(ControlName, out txt);
CurrentLanguage.TryGetValue(ControlName, out txt);
return txt;
}
public CultureInfo Culture
{
get
{
return CurrentUICulture;
}
set
{
CurrentUICulture = value;
}
} #endregion
} class CHS : ILanguages
{
#region ILanguages 成员 public void TryGetValue(string ControlName, out string txt)
{
txt = "标签";
} #endregion
} class Default : ILanguages
{
public Default() {
LanguageValuesDictionary= new SortedDictionary<string, string>();
LoadLanguages();
} IDictionary<string, string> LanguageValuesDictionary;
#region ILanguages 成员 public void TryGetValue(string ControlName, out string txt)
{
//System.Windows.Forms.MessageBox.Show("Test----" + CurrentUICulture.Name.ToString());
//LanguageValuesDictionary = new SortedDictionary<string, string>();
LanguageValuesDictionary.TryGetValue(ControlName, out txt);
//txt = "lable";
} #endregion void LoadLanguages() {
List<string> CtrlValues = new List<string>();
string Input = null; if (File.Exists(System.IO.Path.GetFullPath("Default.lang")) == false)
{ throw new NullReferenceException("Can't Find Default.lang!"); }
StreamReader SR = File.OpenText(System.IO.Path.GetFullPath("Default.lang"));
while ((Input = SR.ReadLine()) != null)
{
CtrlValues.Add(Input); } for (int i = 0; i < CtrlValues.Count - 1; i++)
{
string[] item = CtrlValues[i].Split('=');
if (item.Length >= 2)
{
//注意:要求读入的字符串key值不能相同
//将会报ArgumentException
LanguageValuesDictionary.Add(item[0].TrimEnd(' '), item[1].TrimStart (' ').TrimEnd (';').Trim ('"'));
}
}
SR.Close();
}
}
哪里有下载的呀?
这是winform的老问题了
我希望写完整它,贡献给大家
之前我写得的类在菜单选中英文时有问题,只能在程序启动时写死,这样不好
这里的方法不能全可取,注意你在编码时还有 MessageBox() throw Exception() BackgroundWorker.ReportProgress(1, "获得节目单发布数据");.....
这些都要实现多语言,还能在跨线程取得值
我的问题还没解决我希望是在语言菜单中选某个语言后就能改变界面效果
而菜单事件中只要有一句
ILL.CultureInfo = new System.Globalization.CultureInfo(0x0804);
就能激活事件委托LanguageChangedvoid LanguageChanged(object sender ,LanguageChangedArgs e)里就是 this.buttonOK.Text = e.ILL.GetLanguageValuesByName("FormStart.buttonOK.Text");
this.MessageBox1Vuale = e.ILL.GetLanguageValuesByName("FormStart.MessageBox1 .vuale");
this.MessageBox1Caption = e.ILL.GetLanguageValuesByName("FormStart.MessageBox1.Caption");
用这样的方式刷界面最好
private void StartForm_Load(object sender, EventArgs e)
{
comboBoxLanguageChoose.Items.AddRange(new object[] {"english","chinese" });
LOS = new SubjectLanguageObserver();
LOS.CultureInfoChanged += new SubjectLanguageObserver.CultureInfoEventHandler(LOS_CultureInfoChanged);
LOS.CultureInfoChangeUILanguage(System.Threading.Thread.CurrentThread.CurrentCulture);
//LOS.CultureInfoChangeUILanguage(0x0809);
} private void LOS_CultureInfoChanged(object sender, LocalizableLanguage.SubjectLanguageObserver.CultureInfoEventArgs e)
{
SubjectLanguageObserver LOS = (SubjectLanguageObserver)sender;
//MessageBox.Show(" ..." + LOS.ThisCulture.Name );
this.buttonOK.Text = LOS.languageDictionary.GetLocalizableLanguageByKey("StartForm.buttonOK.Text");
}
private void comboBoxLanguageChoose_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBoxLanguageChoose.SelectedIndex == 0)
{
LOS.CultureInfoChangeUILanguage(0x0809);
}
else if (comboBoxLanguageChoose.SelectedIndex == 1) {
LOS.CultureInfoChangeUILanguage(0x0804);
} }
这是在窗体中的使用方法
楼主看懂了结贴给满分,兄弟们也帮忙测试下,是不是这样写合理!!!?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; }
}
}
#region 生成本地化语言的工厂:LocalizableLanguageFactory
/// <summary>
/// 生成本地化语言的工厂
/// </summary>
public sealed class LocalizableLanguageFactory
{
public LocalizableLanguageFactory() { } private static CultureInfo currentCulture; public static CultureInfo CurrentCulture
{
get { return currentCulture; }
set { currentCulture = value; }
}
public static ILocalizableLanguage CreateLocalizableLanguage()
{ return CreateLocalizableLanguage(currentCulture); }
public static ILocalizableLanguage CreateLocalizableLanguage(CultureInfo CurrentUICulture)
{
ILocalizableLanguage currentLanguage;
switch (CurrentUICulture.LCID)
{
case 0x0004: //zh-Hans 0x0004 中文(简体)
currentLanguage = new Simplified_Chinese("zh-Hans.lang");
break;
case 0x0804: //zh-CN 0x0804 中文(中国)
currentLanguage = new Simplified_Chinese("zh-CN.lang");
break;
case 0x0009://en 英语
currentLanguage = new Default("en.lang");
break;
case 0x0409://en-US 英语(美国)
currentLanguage = new Default("en-US.lang");
break;
case 0x0809://en-GB 英语(英国)
currentLanguage = new Default("en-GB.lang");
break;
default://""(空字符串) 0x007F 固定区域性
currentLanguage = new Default("Default.lang");
break;
}
return currentLanguage;
}
} #endregion
#region 实现AbstractLanguages的各种语言
internal sealed class Default : AbstractLocalizableLanguage
{
public Default()
{
this.LanguageDictionary = new SortedDictionary<string, string>(); }
public Default(string path)
{
LanguageDictionary = new SortedDictionary<string, string>();
LoadLanguageFile(path);
} public override string GetLocalizableLanguageByKey(string ControlKeyName)
{
string txt = string.Empty;
LanguageDictionary.TryGetValue(ControlKeyName, out txt);
return txt;
} public override IDictionary<string, string> LoadLanguageFile(string path)
{
if (string.IsNullOrEmpty(path))
{ throw new ArgumentNullException("Path of Language resource file is null value!"); } List<string> CtrlValues = new List<string>();
string Input = null; if (File.Exists(System.IO.Path.GetFullPath(path)) == false)
{ throw new NullReferenceException("Can't Find Language resource file!"); }
StreamReader SR = File.OpenText(System.IO.Path.GetFullPath(path));
while ((Input = SR.ReadLine()) != null)
{
CtrlValues.Add(Input);
//System.Windows.Forms.MessageBox.Show("Test"+Input);
}
for (int i = 0; i < CtrlValues.Count; i++)
{
string[] item = CtrlValues[i].Split('=');
if (item.Length >= 2)
{
//注意:要求读入的字符串key值不能相同
//将会报ArgumentException
LanguageDictionary.Add(item[0].TrimEnd(' '), item[1].TrimStart(' ').TrimEnd(';').Trim('"'));
}
}
SR.Close();
return LanguageDictionary; }
}
internal sealed class Simplified_Chinese : AbstractLocalizableLanguage
{
public Simplified_Chinese() { this.LanguageDictionary = new SortedDictionary<string, string>(); }
public Simplified_Chinese(string path)
{
this.LanguageDictionary = new SortedDictionary<string, string>();
LoadLanguageFile(path);
} public override string GetLocalizableLanguageByKey(string ControlKeyName)
{
string txt = string.Empty;
LanguageDictionary.TryGetValue(ControlKeyName, out txt);
return txt;
} public override IDictionary<string, string> LoadLanguageFile(string path)
{ if (string.IsNullOrEmpty(path))
{ throw new ArgumentNullException("Path of Language resource file is null value!"); } List<string> CtrlValues = new List<string>();
string Input = null; if (File.Exists(System.IO.Path.GetFullPath(path)) == false)
{ throw new NullReferenceException("Can't Find Language resource file!"); }
StreamReader SR = File.OpenText(System.IO.Path.GetFullPath(path));
while ((Input = SR.ReadLine()) != null)
{
CtrlValues.Add(Input);
//System.Windows.Forms.MessageBox.Show("Test"+Input);
}
for (int i = 0; i < CtrlValues.Count; i++)
{
string[] item = CtrlValues[i].Split('=');
if (item.Length >= 2)
{
//注意:要求读入的字符串key值不能相同
//将会报ArgumentException
LanguageDictionary.Add(item[0].TrimEnd(' '), item[1].TrimStart(' ').TrimEnd(';').Trim('"'));
}
}
SR.Close();
return LanguageDictionary;
}
}
#endregion
在窗体类中,窗体作为观察者,监视CultureInfo对象,
CultureInfo的改变,将激发界面语言的改变,
所以,在form类中建立观察者的基类,并注册事件,
CultureInfo的改变要使得ILocalizableLanguage 接口对象的改变,
而用工厂方法返回依据CultureInfo创建的不同的语言对象!
1.资源文件。
2.xml配置,程序启动时根据用户选择加载对应语言的xml。
我们单位的软件就是多语言的,用的XML
1、字符串储存,这个有好多方法,可以用资源文件、Xml甚至普通文本文件都可以
2、怎么在程序中赋值,这才是麻烦的问题。一般都是在设计界面中给控件设定名称的,而设计界面中只能赋简单的字符串,显然不符合要求。而完全通过在程序中写代码赋值虽然可行,但是少数几个控件可以,成百上千个控件都要这样干就成问题了。我的想法是,在设计界面中设定名称的控件,通过递归遍历所有控件,根据ID或者其他可行的方式查找资源文件里的字符串,并赋值。而对于写代码赋值的,比如动态创建的控件名称、异常信息等等,直接改成从资源文件读取就可以。
具体实施起来可能不止这么简单,最近也需要实现全球化支持,等研究了再来讨论。