资源化,在vc中,是一个文件。我们只要创建对应的语言版本的资源就可以了。但不能实时的自动切换,接触也不深,还没用到需要实时切换语言的功能。前几天看到网友提问,粗略的看了一下,以为有答案,结果2天了,还挂在论坛上,回想当年自己刚工作时的辛苦,不由想写一个实现给他解救一下,呵呵。实际试了一下,还是蛮简单的。
创建一个窗体,在上面放1个Panel,Panel上放一个按钮,这是为了演示嵌套效果,然后Panel外在放2个按钮。依次添加click方法,代码如下,不足120行搞定。
using System; using System.Windows.Forms; using System.Xml; using System.Text; using System.Collections.Generic; using System.IO; using System.Xml.Serialization; namespace CSharpWin05 { public partial class Form1 : Form,IResource { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { //使用方法 /* * 软件首先把界面上所有资源都修改为同一个语言,运行起来,执行一次WindowSerialize.Serialize,保存为对应文件。 * 然后重新修改所有资源的文本为另一个语言,运行,执行一次WindowSerialize.Serialize,保存为对应文件。 * 运行时,使用WindowSerialize.Deserialize对应文件就可以实时切换了。 */ WindowSerialize.Serialize("resource_ch.xml", this); //WindowSerialize.Serialize("resource_en.xml", this); } private void button2_Click(object sender, EventArgs e) { foreach (Form form in Application.OpenForms) { IResource ir = form as IResource; if (ir == null) continue;//只针对处理过的窗体操作 WindowSerialize.Deserialize(ir.EnglishResourcePath, form); } } private void button3_Click(object sender, EventArgs e) { foreach (Form form in Application.OpenForms) { IResource ir = form as IResource; if (ir == null) continue;//只针对处理过的窗体操作 WindowSerialize.Deserialize(ir.ChineseResourcePath, form); } } private void button4_Click(object sender, EventArgs e) { new Form1().Show(); } #region IResource 成员 public string EnglishResourcePath { get { return "resource_en.xml"; } } public string ChineseResourcePath { get { return "resource_ch.xml"; } } #endregion } public interface IResource { string EnglishResourcePath { get; } string ChineseResourcePath { get; } } public static class WindowSerialize { public static void Serialize(string file, Control root) { InnerResource ir = new InnerResource(root); RecursionSerialize(ir, root); XmlSerializer xmlSerializer = new XmlSerializer(typeof(InnerResource)); TextWriter writer = new StreamWriter(file); try { xmlSerializer.Serialize(writer, ir); } finally { writer.Close(); } } public static void RecursionSerialize(InnerResource ir, Control root) { foreach (Control c in root.Controls) { InnerResource irc = new InnerResource(c); ir.Children.Add(irc); if (c.Controls.Count > 0) RecursionSerialize(irc, c); } } public static void Deserialize(string file, Control root) { XmlSerializer xmlSerializer = new XmlSerializer(typeof(InnerResource)); FileStream fs = new FileStream(file, FileMode.Open); InnerResource ir; try { ir = (InnerResource)xmlSerializer.Deserialize(fs); } finally { fs.Close(); } RecursionDeserialize(ir, root); } public static void RecursionDeserialize(InnerResource ir, Control c) { foreach (InnerResource irc in ir.Children) { if (c.Controls[irc.Name] != null) { c.Controls[irc.Name].Text = irc.Text; if (irc.Children.Count > 0) RecursionDeserialize(irc, c.Controls[irc.Name]); } } } } public class InnerResource { public string Name; public string Text; public List<InnerResource> Children = new List<InnerResource>(); public InnerResource() { } public InnerResource(string n, string t) { Name = n; Text = t; } public InnerResource(Control c) { Name = c.Name; Text = c.Text; } } }
我就喜欢贴代码。没办法,这是程序员间沟通最方便,最直接的途径了。
原理很简单,根据帖子楼主的意图,只关心text属性,那就创建一个text<-->name的树形结构,然后自动的序列化到xml,因为ini文件没有树形的结构,xml很合适。