下面介绍一种只需对现有代码做较小改动的方法。
在 Visual Studio 的设计视图中,如果在 Properties 窗口中改变了程序的默认界面语言(Language),我们会注意到无论是工程还是窗体对应的 .Designer.cs 文件都会有显著的改变。比如,我们创建一个叫 MyForm 的 form,并且添加一个叫 MyButton 的按钮。
在改变窗体 Properties 中的 Language 属性之前, .Designer.cs 代码文件中的 InitializeComponent 方法的内容大致如下:
private void InitializeComponent()
{
this.myButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// myButton
//
this.myButton.Location = new System.Drawing.Point(100, 200);
this.myButton.Name = "myButton";
this.myButton.Size = new System.Drawing.Size(75, 23);
this.myButton.TabIndex = 0;
this.myButton.Text = "My Button";
this.myButton.UseVisualStyleBackColor = true;
//
// myForm
//
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.Add(this.myButton);
this.Name = "MyForm";
this.Text = "My Form";
this.ResumeLayout(false);
}
而在改变了窗体 Properties 中的 Language 属性之后,工程中除了默认的 .resx 文件之外,还会自动添加一个 .zh-CHS.resx 文件(假设我们将 Language 改变为 Chinese (Simplified))。另外,.Designer.cs 文件中的 InitializeComponent 方法也会改变成:
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources
= new System.ComponentModel.ComponentResourceManager(typeof(MyForm));
this.myButton = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// myButton
//
this.myButton.AccessibleDescription = null;
this.myButton.AccessibleName = null;
resources.ApplyResources(this.myButton, "myButton");
this.myButton.BackgroundImage = null;
this.myButton.Font = null;
this.myButton.Name = "myButton";
this.myButton.UseVisualStyleBackColor = true;
//
// myForm
//
this.AccessibleDescription = null;
this.AccessibleName = null;
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackgroundImage = null;
this.Controls.Add(this.myButton);
this.Font = null;
this.Icon = null;
this.Name = "myForm";
this.ResumeLayout(false);
}
我们注意到改变 Language 属性之后,代码的主要变化有:
ComponentResourceManager resources = new ComponentResourceManager(typeof(MyForm));
resources.ApplyResources(this.myButton, "myButton");
resources.ApplyResources(this, "$this");
另外,设置控件属性(比如显示文字 Text,控件大小 Size,显示位置 Location 等)的代码都没有了。也就是说设置控件属性的代码都是由 resources.ApplyResource 方法来完成的。那么在我们想改变 WinForm 程序的界面显示语言的时候,能不能直接调用 ApplyResources 方法呢?答案是肯定的。
为 myButton 添加 Click 事件的事件处理函数:
private void myButton_Click(object sender, EventArgs e)
{
int currentLcid = Thread.CurrentThread.CurrentUICulture.LCID;
currentLcid = (currentLcid == 2052) ? 1033 : 2052;
// Changes the CurrentUICulture property before changing the resources that are loaded for the win-form.
Thread.CurrentThread.CurrentUICulture = new CultureInfo(currentLcid);
// Reapplies resources.
ComponentResourceManager resources = new ComponentResourceManager(typeof(MyForm));
resources.ApplyResources(myButton, "myButton");
resources.ApplyResources(this, "$this");
}
当程序运行的时候,点击窗体上的 myButton 按钮,窗体的界面显示语言就会在英语和简体中文之间互相切换。
代码:
1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Windows.Forms;
5 namespace pcd.WinControl
6 {
7 /// <summary>
8 /// 界面语言类型
9 /// </summary>
10 public enum Languge
11 {
12 /// <summary>
13 /// 中文(简体)
14 /// </summary>
15 Chines,
16 /// <summary>
17 /// 英文
18 /// </summary>
19 English
20 };
21 public class MulitLanguage
22 {
23 #region Lang
24 /// <summary>
25 /// 软件界面当前设定语言
26 /// </summary>
27 public static Languge CurLanguge = Languge.Chines;
28 #endregion
29
30 #region GetLang
31 /// <summary>
32 /// 从配置文件中获取界面语言类型
33 /// </summary>
34 private static void GetLangFromConfig()
35 {
36 BroadcastManager.BLL.Global mybloab = new BroadcastManager.BLL.Global();
37 string sl = mybloab.SelectedLanguage;
38 if (sl == "zh-CHS" || sl == "zh-CN")
39 CurLanguge = Languge.Chines;
40 else if (sl == "en-US")
41 CurLanguge = Languge.English;
42 }
43 #endregion
44
45 #region SetLang
46
47 /// <summary>
48 /// 设置当前程序的界面语言
49 /// </summary>
50 /// <param name="lang">language:zh-CN, en-US</param>
51 /// <param name="form">窗体实例</param>
52 /// <param name="formType">窗体类型</param>
53 public static void SetLang(string lang, Form form, Type formType)
54 {
55 System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang);
56 if (form != null)
57 {
58 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(formType);
59 resources.ApplyResources(form, "$this");
60 AppLang(form, resources);
61 }
62 }
63
64 /// <summary>
65 /// 设置当前程序的界面语言
66 /// </summary>
67 /// <param name="form">窗体实例</param>
68 /// <param name="formType">窗体类型</param>
69 public static void SetLang(Form form, Type formType)
70 {
71 GetLangFromConfig();
72 string lang = "zh-CHS";
73 if (CurLanguge == Languge.Chines)
74 lang = "zh-CHS";
75 else if (CurLanguge == Languge.English)
76 lang = "en-US";
77
78 System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang);
79 if (form != null)
80 {
81 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(formType);
82 resources.ApplyResources(form, "$this");
83 AppLang(form, resources);
84 }
85 }
86
87 /// <summary>
88 /// 设置当前程序的界面语言
89 /// </summary>
90 /// <param name="form">用户控件</param>
91 /// <param name="formType">控件类型</param>
92 public static void SetLang(Control control, Type controlType)
93 {
94 GetLangFromConfig();
95 string lang = "zh-CHS";
96 if (CurLanguge == Languge.Chines)
97 lang = "zh-CHS";
98 else if (CurLanguge == Languge.English)
99 lang = "en-US";
100
101 System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang);
102 if (control != null)
103 {
104 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(controlType);
105 resources.ApplyResources(control, "$this");
106 AppLang(control, resources);
107 }
108 }
109
110 #region AppLang for control
111 /// <summary>
112 /// 遍历窗体所有控件,针对其设置当前界面语言
113 /// </summary>
114 /// <param name="control"></param>
115 /// <param name="resources"></param>
116 private static void AppLang(Control control, System.ComponentModel.ComponentResourceManager resources)
117 {
118 if (control is MenuStrip)
119 {
120 resources.ApplyResources(control, control.Name);
121 MenuStrip ms = (MenuStrip)control;
122 if (ms.Items.Count > 0)
123 {
124 foreach (ToolStripMenuItem c in ms.Items)
125 {
126 AppLang(c, resources);
127 }
128 }
129 }
130
131 if (control is ContextMenuStrip)
132 {
133 resources.ApplyResources(control, control.Name);
134 ContextMenuStrip ms = (ContextMenuStrip)control;
135 if (ms.Items.Count > 0)
136 {
137 foreach (ToolStripMenuItem c in ms.Items)
138 {
139 AppLang(c, resources);
140 }
141 }
142 }
143
144 foreach (Control c in control.Controls)
145 {
146 //控件自身
147 resources.ApplyResources(c, c.Name);
148 AppLang(c, resources);
149
150 //控件快捷菜单
151 if (c.ContextMenuStrip != null)
152 AppLang(c.ContextMenuStrip, resources);
153 }
154 }
155 #endregion
156
157 #region AppLang for menuitem
158 /// <summary>
159 /// 遍历菜单
160 /// </summary>
161 /// <param name="item"></param>
162 /// <param name="resources"></param>
163 private static void AppLang(ToolStripMenuItem item, System.ComponentModel.ComponentResourceManager resources)
164 {
165 if (item is ToolStripMenuItem)
166 {
167 resources.ApplyResources(item, item.Name);
168 ToolStripMenuItem tsmi = (ToolStripMenuItem)item;
169 if (tsmi.DropDownItems.Count > 0)
170 {
171 foreach (ToolStripMenuItem c in tsmi.DropDownItems)
172 {
173 AppLang(c, resources);
174 }
175 }
176 }
177 }
178 #endregion
179
180 #endregion
181 }
182 }
183
添加好Form9的各种语言版本资源(Form9.en-US.resx 、Form9.zh-CHS.resx),具体使用如下:
1
2 private void Form9_Load(object sender, EventArgs e)
3 {
4 pcd.WinControl.MulitLanguage.SetLang(this, typeof(Form9));
5 }
6
7 private void button1_Click(object sender, EventArgs e)
8 {
9 if (pcd.WinControl.MulitLanguage.CurLanguge == pcd.WinControl.Languge.Chines)
10 {
11 MessageBox.Show("请先选择", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
12 }
13 else if (pcd.WinControl.MulitLanguage.CurLanguge == pcd.WinControl.Languge.English)
14 {
15 MessageBox.Show("Please Select before Submit", "System Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
16 }
17 }
18 /// <summary>
19 /// 语言选择
20 /// </summary>
21 private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
22 {
23 switch (this.comboBox1.SelectedIndex)
24 {
25 case 0:
26 pcd.WinControl.MulitLanguage.SetLang("zh-CN", this, typeof(Form8));
27
28 break;
29 case 1:
30 pcd.WinControl.MulitLanguage.SetLang("en-US", this, typeof(Form8));
31
32 break;
33 default:
34 pcd.WinControl.MulitLanguage.SetLang("zh-CN", this, typeof(Form8));
35 break;
36 }
37 }
38
MSDN:如何:为 Windows 窗体全球化设置区域性和用户界面的区域性
Visual Basic 或 Visual C# 应用程序的两个区域性值确定了为应用程序加载哪些资源以及如何设置像货币、数字和日期这样的信息的格式。加载的资源由 UI 区域性设置确定,而格式设置选项由区域性设置确定。应用程序首先将在以下位置查找区域性值:CurrentCulture 和 CurrentUICulture 属性。可按下面的过程所示在代码中设置这些值。
CurrentCulture 属性的默认值是操作系统的用户区域设置,它在“区域选项”控制面板中设置。CurrentUICulture 属性的默认值是操作系统的用户界面 (UI) 语言,即您的操作系统用户界面所使用的语言。在 Windows 2000 和 Windows XP MultiLanguage Edition 上,CurrentUICulture 默认为当前用户 UI 语言设置。
在一些情况下,您可能要根据操作系统或用户的区域性设置更改大部分应用程序,但保留数字或日期不更改。您可以用区域性特定类通过固定区域性设置信息的格式,固定区域性与英语语言相关联,但没有特定的区域。有关这些类的更多信息,请参见和 。有关固定区域性的更多信息,请参见 。有关可能有的区域性设置的信息,请参见 。
设置适合于特定区域性的格式设置选项
-
如果要重写用户或操作系统的设置,可以设置 和 属性。
通常,您想要指定一个区域性,以便应用程序用户界面的每一部分都适合于该区域性。因此,您必须在调用 InitializeComponent 方法之前设置该区域性。
复制代码 ' Visual Basic ' Put the Imports statements at the beginning of the code module Imports System.Threading Imports System.Globalization ' Put the following code before InitializeComponent() ' Sets the culture to French (France) Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR") ' Sets the UI culture to French (France) Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR") // C# // Put the using statements at the beginning of the code module using System.Threading; using System.Globalization; // Put the following code before InitializeComponent() // Sets the culture to French (France) Thread.CurrentThread.CurrentCulture = new CultureInfo("fr-FR"); // Sets the UI culture to French (France) Thread.CurrentThread.CurrentUICulture = new CultureInfo("fr-FR");
注意 区域性值必须始终是特定区域性的(如“fr-FR”),而不是非特定区域性的(如“fr”)。这样做的原因在于非特定区域性(例如“fr”)可以应用于所有讲法语的区域性,但在法国、比利时和魁北克(加拿大)使用不同的货币。
-
对于无论 CurrentCulture 属性的值如何设置都应不更改显示的任何字符串,用固定区域性调用格式设置方法。
复制代码 ' Visual Basic Dim MyInt As Integer = 100 Dim MyString As String = MyInt.ToString("C", CultureInfo.InvariantCulture) MessageBox.Show(MyString) // C# int MyInt = 100; string MyString = MyInt.ToString("C", CultureInfo.InvariantCulture); MessageBox.Show(MyString);
// set culture for formatting
Thread.CurrentThread.CurrentCulture = ci;
// set culture for resources
Thread.CurrentThread.CurrentUICulture = ci;