C#winform界面的语言切换
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>