Winform工程界面中英文切换:基于本地化生成资源文件Form.en-US.resx
前言
在一个软件中支持英文、中文两种语言,那么就必须有这两种语言的资源文件,这在Winform中可以采用资源文件(后缀名为.resx)来实现。在Visual Studio开发环境中生成资源文件有两种方式:
1.使项目系统为可本地化的用户界面元素(如窗体上的文本和图像)生成资源文件。然后将该资源文件生成到附属程序集中。上述资源文件称作基于窗体的资源。
2.添加一个资源文件模板然后使用 XML 设计器编辑该模板。采取后一种方法的原因之一是为了生成在对话框和错误信息中出现的可本地化字符串。然后,必须编写代码以访问这些资源。上述资源文件称作项目资源。
通常,应对特定于 Windows 窗体应用程序中的某个窗体的所有资源使用基于窗体的资源。应对所有不是基于窗体的用户界面字符串和图像(如错误消息)使用项目资源。1
本文将介绍如何通过第一种方式实现Winform窗体的中英文切换。
具体步骤
1、原界面
2、改窗体的Localizable属性
进入该窗体的属性界面,改Localizable为True:
3、改窗体的Language属性为英语(美国)
在属性界面,将Language由“默认”改为你要切换的语种,此处选择“英语(美国)”:
4、手动修改英文版界面的字体
修改Language属性后,原有的Form1.cs会自动变为Form1.cs[设计-英文(美国)],这就是英文版的界面了,在此窗体上手动将各控件文本修改为对应英文,修改后窗体为:
这时从解决方案中可以看到,Form1.cs下有两个resx资源文件,Form1.resx为默认窗体的资源文件,Form1.en-US.resx为英文(美国)界面的资源文件:
点击Form1.en-US.resx,可以发现其中存储的即是刚刚修改的英文版界面文本,后续也可以直接在该界面进行文本修改:
5、自动生成[项目名].resources.dll
点击生成后,到生成程序目录下可看到有一个en-US文件夹:
进入文件夹,可看到GroundBondTest.resources.dll,该文件即是存储英文版界面资源的文件:
但这里有个要注意的点,我之前有个项目做到这一步操作时,Debug中怎么都没出现en-US文件夹,后来试了很久才发现是因为我的项目使用了ILMerge程序包,导致将exe程序依赖的dll文件都合并到了exe程序中,所以en-US自然不会出现在最终的执行目录中:
不过在这种情况下,我们可以打开中间目录中obj中的Debug文件夹,就可以看到生成的en-US文件夹了,把它复制到\bin\Debug中即可使用了:
6、实现中英文动态切换
可以看到我的界面有个菜单栏 语言,这是我用来切换语言的控件,也可能用按钮之类的,以中文切成英文为例,点击菜单栏语言>English的事件代码如下:
private void EnglishToolStripMenuItem_Click(object sender, EventArgs e)
{
int currentLcid = 1033; //1033代表英文,2052代表中文
Thread.CurrentThread.CurrentUICulture = new CultureInfo(currentLcid);
ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));
resources.ApplyResources(this, "$this");//窗体标题
foreach (Control control in this.Controls)//循环当前界面所有的控件
{
//将资源与控件对应
resources.ApplyResources(control, control.Name);
if (control.HasChildren)//子控件,比如组合框GroupBox里的控件
{
foreach (Control controls in control.Controls)
resources.ApplyResources(controls, controls.Name);
}
if (control is MenuStrip)//菜单栏控件
{
resources.ApplyResources(control, control.Name);
MenuStrip ms = (MenuStrip)control;
if (ms.Items.Count > 0)
{
//遍历菜单
foreach (ToolStripMenuItem ts in ms.Items)//主菜单
{
resources.ApplyResources(ts, ts.Name);
if (ts.DropDownItems.Count > 0)
{
foreach (ToolStripMenuItem tts in ts.DropDownItems)//子菜单
{
resources.ApplyResources(tts, tts.Name);
}
}
}
}
}
}
//刷新窗体,有时窗体标题无法切换成功,需要刷新一下
this.Refresh();
//存储到Settings中,便于打开程序进行语言初始化
Properties.Settings.Default.DefaultLanguage = 1033;
Properties.Settings.Default.Save();
}
7、语言初始化设置
将设置的语言保存到Properties>Settings中:
即可在窗体加载函数中进行初始化:
private void Form1_Load(object sender, EventArgs e)
{
//获取上次打开程序后设置的语言
currentLcid = Properties.Settings.Default.DefaultLanguage;
//首次根据系统语言设置
if (currentLcid == 0)//若第一次打开该程序,则获取系统的区域标识符
currentLcid = System.Threading.Thread.CurrentThread.CurrentCulture.LCID;
Thread.CurrentThread.CurrentUICulture = new CultureInfo(currentLcid);
ComponentResourceManager resources = new ComponentResourceManager(typeof(Form1));
resources.ApplyResources(this, "$this");//窗体标题
foreach (Control control in this.Controls)//循环当前界面所有的控件
{
//将资源与控件对应
resources.ApplyResources(control, control.Name);
if (control.HasChildren)//子控件,比如组合框GroupBox里的控件
{
foreach (Control controls in control.Controls)
resources.ApplyResources(controls, controls.Name);
}
if (control is MenuStrip)//菜单栏控件
{
resources.ApplyResources(control, control.Name);
MenuStrip ms = (MenuStrip)control;
if (ms.Items.Count > 0)
{
//遍历菜单
foreach (ToolStripMenuItem ts in ms.Items)//主菜单
{
resources.ApplyResources(ts, ts.Name);
if (ts.DropDownItems.Count > 0)
{
foreach (ToolStripMenuItem tts in ts.DropDownItems)//子菜单
{
resources.ApplyResources(tts, tts.Name);
}
}
}
}
}
}
}