代码改变世界

C#中利用Reflection(反射)来实现自动多语言版本功能

2014-01-11 23:31  唐永华  阅读(536)  评论(0编辑  收藏  举报

什么是反射
  Reflection,中文翻译为反射。
  这是.Net中获取运行时类型信息的方式,.Net的应用程序由几个部分:‘程序集(Assembly)’、‘模块(Module)’、‘类型(class)’组成,而反射提供一种编程的方式,让程序员可以在程序运行期获得这几个组成部分的相关信息,例如:

  Assembly类可以获得正在运行的装配件信息,也可以动态的加载装配件,以及在装配件中查找类型信息,并创建该类型的实例。
Type类可以获得对象的类型信息,此信息包含对象的所有要素:方法、构造器、属性等等,通过Type类可以得到这些要素的信息,并且调用之。
MethodInfo包含方法的信息,通过这个类可以得到方法的名称、参数、返回值等,并且可以调用之。
诸如此类,还有FieldInfo、EventInfo等等,这些类都包含在System.Reflection命名空间下。

技术点1: 获取到信息定义类的所有定义变量

using System.Reflection;

public class GlobalDefine
{
string Define_Msg_1 = "Define_Msg_XXX";
public string Define_Msg_2 = "Define_Msg_XXX_2";
}

 

private void button1_Click(object sender, EventArgs e)
{
GlobalDefine tmpClass = new GlobalDefine();
Type tmpReflection = tmpClass.GetType();
System.Reflection.FieldInfo[] fieldinfo = tmpReflection.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
for (int i = 0; i < fieldinfo.Length; i++)
{
TreeNode tsminode = new TreeNode();
tsminode.Name = fieldinfo[i].FieldType.Name;

//fieldinfo[i].Name 表示该变量的定义名称

//fieldinfo[i].GetValue(tmpClass) 表示该变量的对象

tsminode.Text = fieldinfo[i].Name + ":" + fieldinfo[i].GetValue(tmpClass);
treeView2.Nodes.Add(tsminode);
}
}

技术点2: 获得窗体的所有控件

  大部份都是使用下面这种方法来获取,但是这种方法有个致命的弱点就是有很多组件不包含在这里面,如:Listview中的列信息,Timer类型的组件

  foreach (Control ctrl in this.Controls)
  {
  }

  那么我们有没有办法来获取到Form组件上的所有Components呢?  使用反射技术就能实现:

System.Reflection.FieldInfo[] fieldinfo = this.GetType().GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
for (int i = 0; i < fieldinfo.Length; i++)
{

//fieldinfo[i].GetValue(tmpClass) 表示该变量的对象
object tmpobj = fieldinfo[i].GetValue(this);
if (tmpobj is Component)
{
TreeNode tsminode = new TreeNode();
tsminode.Name = fieldinfo[i].FieldType.Name;
tsminode.Text = fieldinfo[i].FieldType.Name + ":" + fieldinfo[i].Name;
treeView2.Nodes.Add(tsminode);

}
}

 

3  如何实现自动多语言版本功能呢?

第一步: 在信息定义类中,以每个窗体组件的名称来定义消息内容:

譬如: 在Form1窗体中有一个button按钮,name: BtnFrmClose          Text:关闭

那么我可以定义为:

  public string BtnFrmClose ="关闭";

或者

  public string Form1_BtnFrmClose ="关闭";

 

第二步:利用技术点1功能和XML文件操作功能,把我们需要翻译的字段保存到文件中,那么就可以翻译成各种需要的语言版本。

           并把XML文件的内容读取到定义类中。

第三步:利用技术点2来扫描需要多语言功能的窗体控件,同时也用技术点1来扫描信息定义类

           当控件的Name等于信息定义类的Name时,则可以利用赋值的方式来给控件设置值,这样就实现了窗体的动态设置。