国际化

    /*
     * 本地化Windows窗体
     * 资源地址:http://msdn.microsoft.com/zh-cn/library/y99d1cd3%28v=vs.110%29.aspx
     */

国际化是桌面端的程序的必不可少的一个功能,基本上每个程序都会需要这样功能,但是多资源的文件来源可以多种多样,包含xml文件、resource资源文件等等,现先介绍这两种多语言文件的实现国际化的方法。

一、resource资源文件

    无论是WPF还是WinForm都对这种资源文件提供支持,切换语言时,只需要设置Thread.CurrentThread.CurrentUICulture就可进行语言的切换。UI使用多语言的方法如下:

   

 1     //定义资源的一个变量
 2     private ResourceManager _resouceManager = null;
 3 
 4         public ApplyResourceFile()
 5         {        
 6             InitializeComponent();
 7 
 8             LoadResource();
 9         }
10 
11         private void LoadResource()
12         {
13             _resouceManager = new ResourceManager("LocalizeWinForm.LanguageResources.Language", typeof(ApplyResourceFile).Assembly);
14         }
15 
16         /// <summary>
17         /// 通过Key得到相应的语言资源文件中定义的文本
18         /// </summary>
19         /// <param name="str"></param>
20         /// <returns></returns>
21         public string GetMsg(string str)
22         {
23             return _resouceManager.GetString(str);
24         }
25 
26         private void rb_English_CheckedChanged(object sender, EventArgs e)
27         {
28             CultureInfo cultureInfo = null;
29             if (rb_English.Checked)
30             {
31                 Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-GB");
32             }
33             else
34             {
35                 Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-Hans");
36             }
37         }

二、XML资源

     1.语言文件定义Language.en-GB.xml

 1        <?xml version="1.0" encoding="utf-8" ?>
 2        <!--本文档集成所有窗体的控件配置-->
 3        <language id="en-GB" name="english">
 4          <btn_Close>Close</btn_Close>
 5          <btn_Ok>Ok</btn_Ok>
 6         <cb_basketball>basketball</cb_basketball>
 7         <cb_football>football</cb_football>
 8         <cb_tennis>tennis</cb_tennis>
 9         <groupBox_FavoriteSport>What is you favorite sport?</groupBox_FavoriteSport>
10         <groupBox_Gender>Gender</groupBox_Gender>
11         <lbl_Age>Age</lbl_Age>
12        <lbl_Name>Name</lbl_Name>
13        <rb_Female>Female</rb_Female>
14        <rb_Male>Male</rb_Male>
15       </language>

    2.简单定义一个XMLHelper类,来处理XML中的数据

 1 internal class XMLHealper
 2     {
 3         #region 字段
 4 
 5         private XmlDocument _xmlDoc = new XmlDocument();
 6 
 7         #endregion
 8 
 9         #region 构造函数
10 
11         public XMLHealper()
12         {
13 
14         }
15 
16         public XMLHealper(string path)
17         {
18             OpenXML(path);
19         }
20 
21         #endregion
22 
23         #region 加载XML文件,创建操作对象
24 
25         /// <summary>
26         /// 加载XML文件,创建操作对象
27         /// </summary>
28         public void OpenXML(string filePath)
29         {
30             try
31             {
32                 if (!string.IsNullOrEmpty(filePath))
33                 {
34                     _xmlDoc.Load(filePath);
35                 }
36             }
37             catch (Exception ex)
38             {
39                 throw ex;
40             }
41         }
42 
43         #endregion
44 
45         #region 得到数据表
46  
47         /// <summary>
48         /// 得到节点数据表
49         /// </summary>
50         /// <returns></returns>
51         public DataView GetNodeData(string tagName)
52         {
53             DataSet ds = null;
54             XmlNodeList nodeList = _xmlDoc.GetElementsByTagName(tagName);
55             if (nodeList == null || nodeList.Count == 0)
56             {
57                 return null;
58             }
59             else
60             {
61                 ds = new DataSet();
62                 XmlNode node = nodeList[0];
63                 StringReader reader = new StringReader(node.OuterXml);
64                 ds.ReadXml(reader);
65                 return ds.Tables[0].DefaultView;
66             }
67         }
68 
69         #endregion
70     }

    3.定义一个LocalizeByXMLFile,实现当语言切换时,能自动获取到当前语言的文本信息

 1 public class LocalizeByXMLFile
 2     {
 3         private string _languageXMLPath = string.Empty;
 4         private string _languageTagName = string.Empty;
 5         private string _languageCode = string.Empty;
 6         private DataRow _resource = null;
 7 
 8         public LocalizeByXMLFile(string languageXMLPath,string languageTagName) 
 9         {
10             _languageXMLPath = languageXMLPath;
11             _languageTagName = languageTagName;
12         }
13 
14         /// <summary>
15         /// Load data from xmlPath
16         /// </summary>
17         /// <param name="languageXMLPath"></param>
18         private void LoadResource(string languageXMLPath)
19         {
20             XMLHealper xh = new XMLHealper(languageXMLPath);
21             DataView dv = xh.GetNodeData(_languageTagName);
22             _resource = dv[0].Row;
23         }
24 
25         /// <summary>
26         /// 判断当前的语言是否与CurrentUICulture相同,如果不同,则需要重新加载XML Data
27         /// </summary>
28         public DataRow Resource
29         {
30             get
31             {
//注意这里只是得到当前线程的UI线程语言,如果程序运行在后台线程,此句段代码只能获取后台线程的线程语言
32 string currentLanguageCode = Thread.CurrentThread.CurrentUICulture.Name; 33 if(_languageCode != currentLanguageCode) 34 { 35 _languageCode = currentLanguageCode; 36 string specialLanguageXMLPath = _languageXMLPath.Insert(_languageXMLPath.LastIndexOf(".") + 1, currentLanguageCode + "."); 37 LoadResource(specialLanguageXMLPath); 38 } 39 return _resource; 40 } 41 set 42 { 43 _resource = value; 44 } 45 } 46 47 /// <summary> 48 /// 获取对应语言的消息 49 /// </summary> 50 /// <param name="str"></param> 51 /// <returns></returns> 52 public string GetMsg(string str) 53 { 54 string val = ""; 55 try 56 { 57 val = Resource[str].ToString(); 58 } 59 catch 60 { 61 // "Cannot Found:" + strId + " , Please Add it to Resource File."; 62 } 63 return val; 64 } 65 }

    4.使用LocalizeByXMLFile来实现多语言

1  private LocalizeByXMLFile _localize = new LocalizeByXMLFile(@"LanguageResourcesLanguage.xml", "language");
2  localizeByXMLFile.GetMsg("key");

三、在特定的项目中如何实现多语言

    1.对于WPF项目而言,可以直接在xaml文件中使用Binding来实现Text的多语言切换,如<TextBox Text = {binding LanguageResource["txtKey"]}>

    2.对于WinForm项目可言,UI的多语言的实现可以稍麻烦一点,可实现一个类来遍历UI中的所有元素,然后然后languageResource的getString()来设置UI的文本。

      

 1   public class LocalizeForm : LocalizeByXMLFile
 2     {
 3         public LocalizeForm(string languageXMLPath, string languageTagName) 
 4             :base(languageXMLPath,languageTagName)
 5         {
 6             
 7         }
 8 
 9         public void FormatUI(System.Windows.Forms.Control control)
10         {
11             control.Text = GetMsg(control.Name);
12             for (int i = 0; i < control.Controls.Count; i++)
13             {
14                 switch (control.Controls[i].GetType().Name)
15                 {
16                     case "Label":
17                     case "Button":
18                     case "CheckBox":
19                     case "RadioButton":
20                     case "LinkLabel":
21                     case "ToolStripMenuItem":
22                         control.Controls[i].Text = GetMsg(control.Controls[i].Name);
23                         break;
24                     case "Panel":
25                     case "GroupBox":
26                     case "TableLayoutPanel":
27                     case "FlowLayoutPanel":
28                         FormatUI(control.Controls[i]);
29                         break;
30                     case "MenuStrip":
31                         MenuStrip msp = (MenuStrip)control.Controls[i];
32                         foreach (ToolStripMenuItem n in msp.Items)
33                         {
34                             FormatMenuItem(n);
35                         }
36                         break;
37                     case "TabControl":
38                         TabControl tbc = (TabControl)control.Controls[i];
39                         for (int j = 0; j < tbc.TabCount; j++)
40                         {
41                             tbc.TabPages[j].Text = GetMsg(tbc.TabPages[j].Name);
42                             FormatUI(tbc.TabPages[j]);
43                         }
44                         break;
45                     default:
46                         break;
47                 }
48             }
49         }
50 
51         /// <summary>
52         /// 匹配ToolStripMenuItem
53         /// </summary>
54         /// <param name="menuItem"></param>
55         private void FormatMenuItem(ToolStripMenuItem menuItem)
56         {
57             if (menuItem.HasDropDownItems == false)
58             {
59                 menuItem.Text = GetMsg(menuItem.Name);
60             }
61             else
62             {
63                 for (int i = 0; i < menuItem.DropDownItems.Count; i++)
64                 {
65                     if (menuItem.DropDownItems[i] is ToolStripSeparator)
66                     {
67                         continue;
68                     }
69                     else
70                     {
71                         FormatMenuItem((ToolStripMenuItem)menuItem.DropDownItems[i]);
72                     }
73                 }
74             }
75         }
76     }

 然后在Form.cs中直接调用如下代码

  /// <summarys>
    ///   <summary>
    ///     1.通过资源文件来设置多语言
    ///   </summary>
    ///   <summary>
    ///     2.通过加载XML文件来设置多语言
    ///   </summary>
    /// </summarys>
    public partial class ApplyResourceFile : Form
    {
        /*
        private ResourceManager _resouceManager = null;

        public ApplyResourceFile()
        {        
            InitializeComponent();
        }

        public override void LoadResource()
        {
            _resouceManager = new ResourceManager("LocalizeWinForm.LanguageResources.Language", typeof(ApplyResourceFile).Assembly);
        }

        /// <summary>
        /// 通过资源文件来设置多语言
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        public override string GetMsg(string str)
        {
            return _resouceManager.GetString(str);
        }

        private void rb_English_CheckedChanged(object sender, EventArgs e)
        {
            CultureInfo cultureInfo = null;
            if (rb_English.Checked)
            {
                cultureInfo = new System.Globalization.CultureInfo("en-GB");
            }
            else
            {
                cultureInfo = new System.Globalization.CultureInfo("zh-Hans");
            }
            SetLanguage(cultureInfo); 
        }
         */
        private LocalizeByXMLFile _localize = new LocalizeByXMLFile(@"LanguageResourcesLanguage.xml", "language");
        private LocalizeForm _localizeForm = new LocalizeForm(@"LanguageResourcesLanguage.xml", "language");

        public ApplyResourceFile()
        {
            InitializeComponent();
        }

        private void rb_English_CheckedChanged(object sender, EventArgs e)
        {
            if (rb_English.Checked)
            {
                Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-GB");
            }
            else
            {
                Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-Hans");
            }
  CultureInfo.DefaultThreadCurrentCulture = Thread.CurrentThread.CurrentUICulture;          
       CultureInfo.DefaultThreadCurrentUICulture = Thread.CurrentThread.CurrentUICulture; }
private void ApplyResourceFile_Load(object sender, EventArgs e) { _localizeForm.FormatUI(this); } }

      

原文地址:https://www.cnblogs.com/JustYong/p/3904117.html