C#的Winform多语言实现(XML文件)

时间:2022-12-04 15:53:44

       使用XML文件实现Winform多语言切换,本博文提供的代码可以实现简体中文、繁体中文、英文的切换。如果需要增加其它语言的切换,只需要编写相应的语言的XML文件即可。 并且,当修改了语言之后,会更新所有打开的窗口。先贴几张图展示一下效果。

程序下载1:点击打开链接

http://download.csdn.net/detail/softimite_zifeng/9731573

程序下载2(升级版):点击打开链接

http://download.csdn.net/detail/softimite_zifeng/9731577

1. 简体中文

C#的Winform多语言实现(XML文件)

2. 繁体中文

C#的Winform多语言实现(XML文件)

3. 英文

C#的Winform多语言实现(XML文件)

下面子丰介绍一下实现的过程:

1. 编写相应语言的XML文件。子丰以英文为例,将同一个窗口中需要更改语言的控件,写一个同一个<Form></Form>的<Controls></Controls>中,如下面所示,为上面两个窗口的XML文件(English.xml)。

<?xml version="1.0" encoding="utf-8" ?>
<Softimite Language="简体中文">
	<Form>
		<!--登录界面-->
		<Name>LoginForm</Name>
		<Controls>
			<Control name="LoginForm" text="Login"/>
			<Control name="accountLab" text="Account"/>
			<Control name="passwordLab" text="Password"/>
			<Control name="languageLab" text="Language"/>
			<Control name="loginBtn" text="Login"/>
			<Control name="passwordBtn" text="Modify pwd"/>
		</Controls>
	</Form>

	<Form>
		<!--修改密码界面-->
		<Name>PasswordForm</Name>
		<Controls>
			<Control name="PasswordForm" text="Modify Password"/>
			<Control name="accountLab" text="Account"/>
			<Control name="passwordLab" text="Old password"/>
			<Control name="newpasswordLab" text="New password"/>
			<Control name="modifyBtn" text="Modify"/>
		</Controls>
	</Form>
</Softimite>

2. 编写一个XML文件(DefaultLanguage.xml),用于保存当前设置的默认语言。当下次启动程序时,会读取该文件,从而将程序的语言设置为上次程序关闭时的语言。

<?xml version="1.0" encoding="utf-8" ?> 
<Softimite Language="默认语言">
	<DefaultLanguage>ChineseSimplified</DefaultLanguage>
</Softimite>


3. 如下图所示,是3种语言的XML文件以及保存默认语言的XML文件。注:必须将这4个XML文件属性中的“ 复制到输出目录”设置为“ 如果较新则复制”,否则,程序在运行过程中会找不到这4个文件。

C#的Winform多语言实现(XML文件)

C#的Winform多语言实现(XML文件)

4. 创建一个静态类(MultiLanguage.cs)用于编写与切换语言相关的变量和代码。

(1)变量DefaultLanguage,用于保存当前默认语言

//当前默认语言
public static string DefaultLanguage = "ChineseSimplified";

(2)函数GetDefaultLanguage用于从DefaultLanguage.xml中读取当前默认语言

/// <summary>
/// 读取当前默认语言
/// </summary>
/// <returns>当前默认语言</returns>
public static string GetDefaultLanguage()
{
    string defaultLanguage = "ChineseSimplified";
    XmlReader reader = new XmlTextReader("Languages/DefaultLanguage.xml");
    XmlDocument doc = new XmlDocument();
    doc.Load(reader);
    XmlNode root = doc.DocumentElement;
    //选取DefaultLangugae节点 
    XmlNode node = root.SelectSingleNode("DefaultLanguage");
    if (node != null)
    {
        //取出节点中的内容 
        defaultLanguage = node.InnerText;
    }
    reader.Close();
    reader.Dispose();
    return defaultLanguage;
}

(3)函数SetDefaultLanguage修改当前默认语言

/// <summary>
/// 修改默认语言
/// </summary>
/// <param name="lang">待设置默认语言</param>
public static void SetDefaultLanguage(string lang)
{
    DataSet ds = new DataSet();
    ds.ReadXml("Languages/DefaultLanguage.xml");
    DataTable dt = ds.Tables["Softimite"];
    dt.Rows[0]["DefaultLanguage"] = lang;
    ds.AcceptChanges();
    ds.WriteXml("Languages/DefaultLanguage.xml");
    DefaultLanguage = lang;
}

(4)函数ReadXMLText用于从XML语言文件中读取控件在该语言下的值

/// <summary>
/// 从XML文件中读取需要修改Text的內容
/// </summary>
/// <param name="frmName">窗口名,用于获取对应窗口的那部分内容</param>
/// <param name="lang">目标语言</param>
/// <returns></returns>
private static Hashtable ReadXMLText(string frmName, string lang)
{
    try
    {
        Hashtable hashResult = new Hashtable();
        XmlReader reader = null;
        //判断是否存在该语言的配置文件
        if (!(new System.IO.FileInfo("Languages/" + lang + ".xml")).Exists)
        {
            return null;
        }
        else
        {
            reader = new XmlTextReader("Languages/" + lang + ".xml");
        }
        XmlDocument doc = new XmlDocument();
        doc.Load(reader);
        XmlNode root = doc.DocumentElement;
        //获取XML文件中对应该窗口的内容
        XmlNodeList nodeList = root.SelectNodes("Form[Name='" + frmName + "']/Controls/Control");
        foreach (XmlNode node in nodeList)
        {
            try
            {
                //修改内容为控件的Text值
                XmlNode node1 = node.SelectSingleNode("@name");
                XmlNode node2 = node.SelectSingleNode("@text");
                if (node1 != null)
                {
                    hashResult.Add(node1.InnerText.ToLower(), node2.InnerText);
                }
            }
            catch { }
        }
        reader.Close();
        reader.Dispose();
        return hashResult;
    }
    catch
    {
        return null;
    }
}

(5)函数LoadLanguage用于加载语言或切换语言

/// <summary>
/// 加载语言
/// </summary>
/// <param name="form">加载语言的窗口</param>
public static void LoadLanguage(Form form)
{
    //获取当前默认语言
    string language = GetDefaultLanguage();
    //根据用户选择的语言获得表的显示文字 
    Hashtable hashText = ReadXMLText(form.Name, language);
    if (hashText == null)
    {
        return;
    }
    //获取当前窗口的所有控件
    Control.ControlCollection sonControls = form.Controls;
    try
    {
        //遍历所有控件
        foreach (Control control in sonControls)
        {
            if (control.GetType() == typeof(Panel))     //Panel
            {
                GetSetSubControls(control.Controls, hashText);
            }
            else if (control.GetType() == typeof(GroupBox))     //GroupBox
            {
                GetSetSubControls(control.Controls, hashText);
            }
            else if (control.GetType() == typeof(TabControl))       //TabControl
            {
                GetSetSubControls(control.Controls, hashText);
            }
            else if (control.GetType() == typeof(TabPage))      //TabPage
            {
                GetSetSubControls(control.Controls, hashText);
            }
            if (hashText.Contains(control.Name.ToLower()))
            {
                control.Text = (string)hashText[control.Name.ToLower()];
            }
        }
        if (hashText.Contains(form.Name.ToLower()))
        {
            form.Text = (string)hashText[form.Name.ToLower()];
        }
    }
    catch { }
}

/// <summary>
/// 获取并设置控件中的子控件
/// </summary>
/// <param name="controls">父控件</param>
/// <param name="hashResult">哈希表</param>
private static void GetSetSubControls(Control.ControlCollection controls, Hashtable hashText)
{
    try
    {
        foreach (Control control in controls)
        {
            if (control.GetType() == typeof(Panel))     //Panel
            {
                GetSetSubControls(control.Controls, hashText);
            }
            else if (control.GetType() == typeof(GroupBox))     //GroupBox
            {
                GetSetSubControls(control.Controls, hashText);
            }
            else if (control.GetType() == typeof(TabControl))       //TabControl
            {
                GetSetSubControls(control.Controls, hashText);
            }
            else if (control.GetType() == typeof(TabPage))      //TabPage
            {
                GetSetSubControls(control.Controls, hashText);
            }
            if (hashText.Contains(control.Name.ToLower()))
            {
                control.Text = (string)hashText[control.Name.ToLower()];
            }
        }
    }
    catch (Exception ex)
    {
        throw new Exception(ex.Message);
    }
}


5. 在主窗口的Load事件中调用函数MultiLanguage.GetDefaultLanguage读取DefaultLanguage.xml,并将ComboBox赋值为当前默认语言,即简体中文、繁体中文或英文。

private void LoginForm_Load(object sender, EventArgs e)
{
    //设置combobox的值
    string language = MultiLanguage.GetDefaultLanguage();
    if (language == "ChineseSimplified")
    {
        languageTxt.Text = "简体中文(默认)";
    }
    else if (language == "Chinese")
    {
        languageTxt.Text = "繁體中文";
    }
    else if (language == "English")
    {
        languageTxt.Text = "English";
    }
}


6. 在每个窗口的Load事件中调用函数MultiLanguage.LoadLanguage,使窗口在出现时即显示为当前默认语言。

private void PasswordForm_Load(object sender, EventArgs e)
{
    //加载语言
    MultiLanguage.LoadLanguage(this);
}


7. 编写用于切换语言的ComboBox的SelectedIndexChanged事件,使得当用于选择对应的语言时,程序会切换到该语言。

//切换语言
private void languageTxt_SelectedIndexChanged(object sender, EventArgs e)
{
    languageTxt.Enabled = false;
    if (languageTxt.Text == "简体中文(默认)")
    {
        //修改默认语言
        MultiLanguage.SetDefaultLanguage("ChineseSimplified");
        //对所有打开的窗口重新加载语言
        foreach (Form form in Application.OpenForms)
        {
            MultiLanguage.LoadLanguage(form);
        }
    }
    else if (languageTxt.Text == "繁體中文")
    {
        //修改默认语言
        MultiLanguage.SetDefaultLanguage("Chinese");
        //对所有打开的窗口重新加载语言
        foreach (Form form in Application.OpenForms)
        {
            MultiLanguage.LoadLanguage(form);
        }
    }
    else if (languageTxt.Text == "English")
    {
        //修改默认语言
        MultiLanguage.SetDefaultLanguage("English");
        //对所有打开的窗口重新加载语言
        foreach (Form form in Application.OpenForms)
        {
            MultiLanguage.LoadLanguage(form);
        }
    }
    languageTxt.Enabled = true;
}

8. 此外,子丰还对上述代码进行了完善和改进。

(1) 使用配置文件App.config代替DefaultLanguage.xml文件保存当前默认语言

(2) 实现DataGridView控件的列头的语言切换

(3) 对上述代码可能出现的异常进行的处理和提示

程序下载(升级版):点击打开链接

http://download.csdn.net/detail/softimite_zifeng/9731577

C#的Winform多语言实现(XML文件)

C#的Winform多语言实现(XML文件)

C#的Winform多语言实现(XML文件)