首页 > 代码库 > 国际化

国际化

国际化是桌面端的程序的必不可少的一个功能,基本上每个程序都会需要这样功能,但是多资源的文件来源可以多种多样,包含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             else34             {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         #endregion22 23         #region 加载XML文件,创建操作对象24 25         /// <summary>26         /// 加载XML文件,创建操作对象27         /// </summary>28         public void OpenXML(string filePath)29         {30             try31             {32                 if (!string.IsNullOrEmpty(filePath))33                 {34                     _xmlDoc.Load(filePath);35                 }36             }37             catch (Exception ex)38             {39                 throw ex;40             }41         }42 43         #endregion44 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             else60             {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         #endregion70     }

    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 xmlPath16         /// </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 Data27         /// </summary>28         public DataRow Resource29         {30             get31             {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             set42             {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             try56             {57                 val = Resource[str].ToString();58             }59             catch60             {61                 // "Cannot Found:" + strId + " , Please Add it to Resource File.";62             }63             return val;64         }65     }

    4.使用LocalizeByXMLFile来实现多语言

1  private LocalizeByXMLFile _localize = new LocalizeByXMLFile(@"LanguageResources\Language.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         /// 匹配ToolStripMenuItem53         /// </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             else62             {63                 for (int i = 0; i < menuItem.DropDownItems.Count; i++)64                 {65                     if (menuItem.DropDownItems[i] is ToolStripSeparator)66                     {67                         continue;68                     }69                     else70                     {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(@"LanguageResources\Language.xml", "language");        private LocalizeForm _localizeForm = new LocalizeForm(@"LanguageResources\Language.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");            }        }        private void ApplyResourceFile_Load(object sender, EventArgs e)        {            _localizeForm.FormatUI(this);        }        private void btn_Ok_Click(object sender, EventArgs e)        {            Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("zh-Hans");            _localizeForm.FormatUI(this);        }    }