本文转自:http://apps.hi.baidu.com/share/detail/16193292
本文作者(郭庆华,朱战立),请您在阅读本文时尊重作者版权。
摘要:为了实现软件界面的动态存储,提出了一种在C#.Net环境下,利用反射技术实现软件界面动态存储的可行性方法。介绍了反射技术和XML 的优势特点,给出了进行界面动态存储的具体实现和关键代码。此方法利用反射技术动态绑定界面控件的属性,提高了程序代码的可复用性与灵活性。
关键词:反射技术;XML;软件界面;序列化Use C#. Net Reflection Technology to Achieve Dynamic Storage of Software Interface
GUO Qing-hua, ZHU Zhan-li
(School of Computer Science, Xi'an Shiyou University, Xi'an 710065, China)
Abstract: In order to achieve dynamic storage of the software interface, the feasibility method is presented that using Reflective technology achieves the dynamic storage of User Interface(UI) in C#.Net environments. Introduce the advantages of reflection technology and XML, and it gives the concrete realization of dynamic storage and key code. This method uses Reflection technology to dynamic bind the properties of UI Controls and improve the program code reusability and flexibility.
Key words: reflection techniques; XML; software interface;Serialization
1 概述
在数据库管理软件开发过程中,个性化的界面设计是一个成功软件产品必不可少的重要组成部分,定制界面设计就是界面控件的布局、控件属性的设置,当然 要考虑界面控件的合理存储的问题。但是传统的软件界面设计为了满足客户的需求,程序员需要开发出各种各样的用户界面,这样既提高软件的开发成本,也浪费大 量的人力和物力,其实那些界面功能大致相同,只是表现形式不同。
本文提出一种使用反射技术获取运行时的界面控件属性的可行性方法,解决了界面的动态存储问题,避免了软件界面的重复开发,提高了软件的开发效率。
2 反射机制
C#.Net提供的反射机制,再结合自适应数据参数的传递,可以将应用框架中的扩展点以插件式程序集的方式来动态加载和构建,从而实现可动态扩展的 应用程序。
2.1 反射机制的基本原理
反射是C#.Net中获取运行时类型信息的方式。C#.Net的应用程序由程序集(Assembly)、模块(Module)和类型(class) 组成,反射提供一种编程的方式,让程序员可以在程序运行时获得这几部分的相关信息。如在运行时获得C#.Net中每一个类型(包括类、结构、委托、接口和 枚举等)的成员属性、成员方法、事件和构造函数等。还可以获得每个成员的名称、限定符和参数。
2.2 反射机制类的层次
C#.Net反射API实际上是一种类的数据结构。图1中显示了这种结构的一部分——这是在命名空间System.Reflection定义的。这 些类能够在逻辑上遍历组合体和类型信息,可以在这个层次结构的任何位置开始,这取决于应用程序的具体设计需要。
2.3 反射机制的作用
应用程序结构分为应用程序域、程序集、模块、类型、成员几个层次。公共语言运行库加载器管理应用程序域,这种管理包括将每个程序集加载到相应的应用 程序域以及控制每个程序集中类型层次结构的内存布局。
程序集包含模块,而模块包含类型,类型又包含成员,反射则提供了封装程序集、模块和类型的对象。可以使用反射动态地创建类型的实例,将类型绑定到现 有对象或从现有对象中获取类型,然后调用类型的方法或访问其字段和属性。
反射通常具有以下用途:①使用Assembly定义和加载程序集,加载在程序集清单中列出的模块,以及从程序集中查找类型并创建该类型的实例;②使 用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法;③使用MethodInfo了解方 法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等;④使用FiedInfo了解字段的名称、访问修饰符和实现详细信息(如 static)等,并获取或设置字段值;⑤使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除 事件处理程序;⑥使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型、只读或可写状态等。
3 软件界面的动态存储
界面的动态存储是指通过软件的工具箱与属性窗口来定制软件界面,界面中所有控件都是窗体的对象,当存储界面时,使用C#.Net反射技术来动态获取 绑定对象的属性,并且存储在XML文件中。
3.1 动态存储的存储格式
需要解决数据采用何种存储格式。XML目前正在成为各种数据库特别是文档的首选格式,由于其具有标记不同字段的能力,使得数据存储变得更简单和动态 化,而且文件的XML存储系统简单并容易实现。所以,存储格式采用XML格式。
3.2 动态存储的实现原理
在C#.Net FrameWork 开发平台中,窗体(即用户看到的软件界面)是一个容器型控件,可以在窗体中添加各类控件(如 Button按钮、TextBox文本框以及其他容器型控件)。软件设计者在设计应用程序的用户界面时,通常先静态创建一个窗体,然后在窗体中根据功能需 求来添加控件、设置属性、创建事件处理程序,以及向窗体添加业务逻辑等。在C#.Net环境中,容器型控件中各控件对象的动态布局都是由相应对象的属性来 决定的,其中对象属性包括属性名以及对应的属性值,通过C#.Net反射机制来动态捕获定制界面中各对象拥有的属性,而且把属性名和属性值使用迭代的方法 分别保存到动态数组中,然后把属性名作为标记,把属性值作为标记的内容,通过循环的方法将属性的数据序列化成XML格式文件。其实现过程如图2所示。
本文作者(郭庆华,朱战立),请您在阅读本文时尊重作者版权。
3.3 动态存储的具体实现
由于界面由许多控件组成,相应的程序设计也比较复杂,为了叙述的简便,这里以软件界面只有Button控件为例来说明界面动态存储的具体实现。
使用C#.Net环境实现软件界面动态存储,首先要创建一个工程项目,然后在窗体上拖放一个Button控件。此时,Button控件就成为窗体的 一个对象,这里给此窗体起名为UIDesigner,Button对象起名为button1。接着需要利用“属性窗口”对Button对象设置相应的属 性。
软件界面的Button对象完成定制设置后,就可以进行动态存储了。对于一个界面中自定义的控件,其方法和属性对于装载软件来说是不确定的。在 C#.Net平台还提供了动态加载对象和动态调用对象的方法,通过C#.Net反射技术来达到目的。实现方法为:首先在工程的命名空间中创建 ButtonObject类、Properties类、PropertyType类、PropertyTypeManager类、PropertyX类 (包括PropertyColor类、PropertyString类、PropertyBoolen类、PropertyFont类、 PropertySize类等)。其关键类为Properties。首先要添加相关引用 using System.Reflecttion、using System.Xml 和 using System.Xml.Serialization,然后在类中创建两个动态数组PropertyValues[]、PropertyInfos[]。其 中,PropertyValues[]用来保存button1的属性名/属性值,PropertyInfos[]用来保存button1的属性类型/属性 全名。所使用到的类图及其关系如图3所示。
依据图3最后完成程序实际。在窗体UIDesigner代码的load_UIDesigner事件中,把button1定义为自定义 ButtonObject类的对象并实例化,然后通过图3中⑴→⑵→⑶→⑷ 四个模块就可以实现把界面控件的属性提取出来,然后把它们分别保存到PropertyInfo、PropertyValue动态数组中。
4 结束语
利用C#.Net平台下反射技术、采用软件界面动态存储的设计思想,动态提取界面控件的属性,以XML文件格式存储,可以将应用框架中的扩展点以插 件式程序集的方式来动态加载和构建,从而实现可动态扩展的应用程序。实践证明,这种方法可极大地提高软件开发的效率,能很好地实现应用系统之间的元数据信 息动态存储,具有较高的扩展性和代码复用性。
参考文献:
[1] Archer T. C#技术内幕[M]. 侯晓霞, 柴宏辉,译. 北京:清华大学出版社,2002.
[2] Richter J. .NET框架程序设计(修订版)[M]. 李建忠,译. 北京:清华大学出版社,2007.
[3] Watson K,Nagel C. C#入门经典[M]. 康博,译.北京:清华大学出版社,2006.