C#winform界面的语言切换

25 篇文章 2 订阅

1、效果图

2、导入导出 

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace LanguageSwitch
{
    public enum Language
    {
        /// <summary>
        /// 英文
        /// </summary>
        en,
        /// <summary>
        /// 中文简体
        /// </summary>
        zh_cn,
    }

    public class ComponentControl
    {
        public Type Type { get; set; }

        public string NameTag { get; set; }

        public string TextTag { get; set; }
    }

    public class XmlLang
    {
        Form _form;
        List<ComponentControl> _listComponent;
        public XmlLang(Form form)
        {
            _form = form;
            _listComponent = new List<ComponentControl>();
        }

        public XmlLang(Form form, List<ComponentControl> listComponent) : this(form)
        {
            _listComponent = listComponent;
        }

        public void Load(Language lang)
        {
            Type type = _form.GetType();
            string xmlPath = string.Format("Language\\{0}\\{1}.xml", lang, type.Namespace.Replace('.', '\\'));
            string dire = Path.GetDirectoryName(xmlPath);
            Directory.CreateDirectory(dire);

            if (!File.Exists(xmlPath))  //不存在xml文件,创建文件并写入根节点
            {
                using (StreamWriter streamWriter = new StreamWriter(xmlPath, false, Encoding.UTF8))
                {
                    streamWriter.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                    streamWriter.WriteLine("<!DOCTYPE Root[");
                    streamWriter.WriteLine("	<!ELEMENT Form ANY>");
                    streamWriter.WriteLine("	<!ATTLIST Form Name ID #REQUIRED>");
                    streamWriter.WriteLine("]>");
                    streamWriter.WriteLine("<Root>");
                    streamWriter.WriteLine("</Root>");
                }
            }
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlPath);
            XmlNode xmlNode = xmlDoc.GetElementById(_form.Name);
            if (xmlNode == null)  //不存在该名称的窗体节点就写入默认的值
            {
                XmlNode root = xmlDoc.DocumentElement;
                addNode(xmlDoc, root, _form);
                xmlDoc.Save(xmlPath);
            }
            setControlText(xmlDoc, _form);
        }

        void addNode(XmlDocument xmlDoc, XmlNode xmlNode, Control ctr)
        {
            Type type = ctr.GetType();
            XmlElement xmlElement = xmlDoc.CreateElement(ctr is Form ? "Form" : type.Name);
            setAttribute(xmlElement, ctr.Name, ctr.Text);
            xmlNode.AppendChild(xmlElement);
            setComponent(xmlDoc, xmlElement, ctr);
            foreach (Control c in ctr.Controls)
            {
                addNode(xmlDoc, xmlElement, c);
            }
        }

        void setAttribute(XmlElement xmlElement, string name, string text)
        {
            xmlElement.SetAttribute("Name", name);
            double num;
            if (!string.IsNullOrWhiteSpace(text) && !double.TryParse(text.Trim(), out num))
            {
                xmlElement.SetAttribute("Text", text);
            }
        }

        void setComponent(XmlDocument xmlDoc, XmlNode xmlNode, Control ctr)
        {
            Type t = ctr.GetType();
            FieldInfo[] fieldInfos = t.GetFields(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.NonPublic);
            foreach (FieldInfo field in fieldInfos)
            {
                foreach (ComponentControl com in _listComponent)
                {
                    if (com.Type.IsAssignableFrom(field.FieldType))
                    {
                        object val = field.GetValue(ctr);
                        if (val != null)
                        {
                            XmlElement xmlElement = xmlDoc.CreateElement(field.FieldType.Name);
                            string name = getValue(val, com.Type, com.NameTag);
                            if (name != null)
                            {
                                string text = getValue(val, com.Type, com.TextTag);
                                setAttribute(xmlElement, name, text);
                                xmlNode.AppendChild(xmlElement);
                            }
                        }
                    }
                }
            }
        }

        string getValue(object val, Type type, string tag)
        {
            PropertyInfo propertyInfo = type.GetProperty(tag);
            if (propertyInfo != null)
            {
                object value = propertyInfo.GetValue(val, null);
                if (value != null)
                {
                    return (string)value;
                }
            }
            return null;
        }

        void setControlText(XmlDocument xmlDoc, Form form)
        {
            XmlNode xmlNode = xmlDoc.GetElementById(form.Name);
            if (xmlNode != null)
            {
                setCtrText(xmlNode, form);
            }
        }

        void setCtrText(XmlNode xmlNode, Control ctr)
        {
            XmlAttribute xmlAttribute = xmlNode.Attributes["Text"];
            if (xmlAttribute != null)
            {
                ctr.Text = xmlAttribute.Value;
            }
            Dictionary<object, ComponentControl> dictComponent = getComponent(ctr);
            foreach (XmlNode node in xmlNode.ChildNodes)
            {
                XmlAttribute attributeName = node.Attributes["Name"];
                if (attributeName != null)
                {
                    string attriName = attributeName.Value;
                    Control currCtr = ctr.Controls[attriName];
                    if (currCtr != null)
                    {
                        setCtrText(node, currCtr);
                    }
                    else
                    {
                        XmlAttribute nodeAttribute = node.Attributes["Text"];
                        if (nodeAttribute != null)
                        {
                            foreach (var kv in dictComponent)
                            {
                                string propertyName = getValue(kv.Key, kv.Value.Type, kv.Value.NameTag);
                                if (propertyName != null && propertyName == attriName)
                                {
                                    PropertyInfo propertyText = kv.Value.Type.GetProperty(kv.Value.TextTag);
                                    if (propertyText != null)
                                    {
                                        propertyText.SetValue(kv.Key, nodeAttribute.Value, null);
                                    }
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }

        Dictionary<object, ComponentControl> getComponent(Control ctr)
        {
            Dictionary<object, ComponentControl> dictT = new Dictionary<object, ComponentControl>();
            Type typeCtr = ctr.GetType();
            FieldInfo[] flds = typeCtr.GetFields(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.NonPublic);
            foreach (FieldInfo field in flds)
            {
                foreach (ComponentControl com in _listComponent)
                {
                    if (com.Type.IsAssignableFrom(field.FieldType))
                    {
                        object val = field.GetValue(ctr);
                        if (val != null)
                        {
                            PropertyInfo nameInfo = com.Type.GetProperty(com.NameTag);
                            if (nameInfo != null)
                            {
                                dictT[val] = com;
                            }
                        }
                    }
                }
            }
            return dictT;
        }


    }
}

3、界面调用 

 由于不是所有控件都继承Control类,所以在遍历窗体中的控件时不能加载这些控件。例如:DataGridViewTextBoxColumn,ToolStripMenuItem

 所以需要自己指定是哪些控件,也不是所有控件显示的文本都是Text,所以也需自己指定NameTag和TextTag。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    XmlLang _xmlLang;
    private void Form1_Load(object sender, EventArgs e)
    {
        _xmlLang = new XmlLang(this, new List<ComponentControl>()
        {
            new ComponentControl() { Type = typeof(ToolStripItem), NameTag = "Name", TextTag = "Text" },
            new ComponentControl() { Type = typeof(DataGridViewColumn), NameTag = "Name", TextTag = "HeaderText" },
        });
        _xmlLang.Load(Language.zh_cn);
    }

    private void 简体中文ToolStripMenuItem_Click(object sender, EventArgs e)
    {
        _xmlLang.Load(Language.zh_cn);
    }

    private void englishToolStripMenuItem_Click(object sender, EventArgs e)
    {
        _xmlLang.Load(Language.en);
    }
}

4、XML 

中文XML:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Root[
	<!ELEMENT Form ANY>
	<!ATTLIST Form Name ID #REQUIRED>
]>
<Root>
  <Form Name="Form1" Text="简历">
    <ToolStripMenuItem Name="toolStripMenuItem2" Text="你好" />
    <ToolStripSeparator Name="toolStripSeparator1" />
    <ToolStripMenuItem Name="简体中文ToolStripMenuItem" Text="简体中文" />
    <ToolStripMenuItem Name="englishToolStripMenuItem" Text="English" />
    <DataGridViewTextBoxColumn Name="dgvColumn1" Text="时间" />
    <DataGridViewTextBoxColumn Name="dgvColumn2" Text="地点" />
    <DataGridViewCheckBoxColumn Name="dgvColumn3" Text="进行中" />
    <TabControl Name="tabControl1">
      <TabPage Name="tabPage1" Text="教育经历">
        <Panel Name="panel1">
          <DataGridView Name="dataGridView1">
            <HScrollBar Name="" />
            <VScrollBar Name="" />
          </DataGridView>
        </Panel>
      </TabPage>
      <TabPage Name="tabPage2" Text="工作经历">
        <Panel Name="panel2" />
      </TabPage>
    </TabControl>
    <PictureBox Name="pictureBox1" />
    <Label Name="label3" Text="个人简介" />
    <GroupBox Name="groupBox3" Text="基本信息">
      <TextBox Name="textBox2" />
      <Label Name="label2" Text="年龄" />
      <Button Name="button3" Text="确定" />
      <RadioButton Name="radioButton2" Text="女" />
      <TextBox Name="textBox1" />
      <RadioButton Name="radioButton1" Text="男" />
      <Label Name="label1" Text="姓名" />
    </GroupBox>
  </Form>
</Root>

英文XML: 

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE Root[
	<!ELEMENT Form ANY>
	<!ATTLIST Form Name ID #REQUIRED>
]>
<Root>
  <Form Name="Form1" Text="Resume">
    <ToolStripMenuItem Name="toolStripMenuItem2" Text="Hello" />
    <ToolStripSeparator Name="toolStripSeparator1" />
    <ToolStripMenuItem Name="简体中文ToolStripMenuItem" Text="简体中文" />
    <ToolStripMenuItem Name="englishToolStripMenuItem" Text="English" />
    <DataGridViewTextBoxColumn Name="dgvColumn1" Text="Time" />
    <DataGridViewTextBoxColumn Name="dgvColumn2" Text="Place" />
    <DataGridViewCheckBoxColumn Name="dgvColumn3" Text="Ing" />
    <TabControl Name="tabControl1">
      <TabPage Name="tabPage1" Text="Education">
        <Panel Name="panel1">
          <DataGridView Name="dataGridView1">
            <HScrollBar Name="" />
            <VScrollBar Name="" />
          </DataGridView>
        </Panel>
      </TabPage>
      <TabPage Name="tabPage2" Text="Work">
        <Panel Name="panel2" />
      </TabPage>
    </TabControl>
    <PictureBox Name="pictureBox1" />
    <Label Name="label3" Text="Personal Information" />
    <GroupBox Name="groupBox3" Text="Information">
      <TextBox Name="textBox2" />
      <Label Name="label2" Text="Age" />
      <Button Name="button3" Text="Confirm" />
      <RadioButton Name="radioButton2" Text="Female" />
      <TextBox Name="textBox1" />
      <RadioButton Name="radioButton1" Text="Male" />
      <Label Name="label1" Text="Name" />
    </GroupBox>
  </Form>
</Root>

 

 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Bridge_go

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值