下面介绍一种只需对现有代码做较小改动的方法。
在 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();
-
-
-
- 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;
-
-
-
- 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();
-
-
-
- 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;
-
-
-
- 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;
-
-
- Thread.CurrentThread.CurrentUICulture = new CultureInfo(currentLcid);
-
-
- ComponentResourceManager resources = new ComponentResourceManager(typeof(MyForm));
- resources.ApplyResources(myButton, "myButton");
- resources.ApplyResources(this, "$this");
- }
当程序运行的时候,点击窗体上的 myButton 按钮,窗体的界面显示语言就会在英语和简体中文之间互相切换。
以下是有可能用的帮助方法
1 SetLang#region SetLang
2 /**//// <summary>
3 /// 设置当前程序的界面语言
4 /// </summary>
5 /// <param name="lang">language:zh-CN, en-US</param>
6 /// <param name="form">窗体实例</param>
7 /// <param name="formType">窗体类型</param>
8 public static void SetLang(string lang, Form form, Type formType)
9 {
10 System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(lang);
11 if (form != null)
12 {
13 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(formType);
14 resources.ApplyResources(form, "$this");
15 AppLang(form, resources);
16 }
17 }
18
19 AppLang for control#region AppLang for control
20 /**//// <summary>
21 /// 遍历窗体所有控件,针对其设置当前界面语言
22 /// </summary>
23 /// <param name="control"></param>
24 /// <param name="resources"></param>
25 private static void AppLang(Control control, System.ComponentModel.ComponentResourceManager resources)
26 {
27 if (control is MenuStrip)
28 {
29 resources.ApplyResources(control, control.Name);
30 MenuStrip ms = (MenuStrip)control;
31 if (ms.Items.Count > 0)
32 {
33 foreach (ToolStripMenuItem c in ms.Items)
34 {
35 AppLang(c, resources);
36 }
37 }
38 }
39
40 foreach (Control c in control.Controls)
41 {
42 resources.ApplyResources(c, c.Name);
43 AppLang(c, resources);
44 }
45 }
46 #endregion
47
48 AppLang for menuitem#region AppLang for menuitem
49 /**//// <summary>
50 /// 遍历菜单
51 /// </summary>
52 /// <param name="item"></param>
53 /// <param name="resources"></param>
54 private static void AppLang(ToolStripMenuItem item, System.ComponentModel.ComponentResourceManager resources)
55 {
56 if (item is ToolStripMenuItem)
57 {
58 resources.ApplyResources(item, item.Name);
59 ToolStripMenuItem tsmi = (ToolStripMenuItem)item;
60 if (tsmi.DropDownItems.Count > 0)
61 {
62 foreach (ToolStripMenuItem c in tsmi.DropDownItems)
63 {
64 AppLang(c, resources);
65 }
66 }
67 }
68 }
69 #endregion
70
71 #endregion