编辑任何任意对象的通用用户控件






4.50/5 (7投票s)
本文将深入探讨反射如何在开发通用的桌面用户控件界面中发挥作用。
引言
任何程序集(.NET DLL)中的任意数据类型都可以被实例化(创建)、探索(有哪些字段)和由用户修改(只要用户满足程序集提供者的安全标准)。
本文将深入探讨反射如何在开发通用的桌面用户控件界面中发挥作用。它将引导您创建通用的 Windows Form,该 Form 将接受用户输入任何任意对象。
背景
反射的力量在于开发者的创造力。反射已被证明在 Java 和 .NET 语言的许多框架中都很有用。但是,我们应该了解在应用程序中使用反射的性能影响。Joel Pobar 的一篇关于 .NET 中性能影响的文章值得阅读:http://msdn.microsoft.com/en-us/magazine/cc163759.aspx。随着越来越多的项目在业务解决方案中使用面向服务架构(原子功能和无状态操作是成功服务提供的关键),这增加了质量控制所需的测试用例数量。有关在此控制在应用程序中使用的实际示例,请参阅 SoapPanda(一个用于测试 Web 服务的 SOAP 客户端)。我想就这个主题说这么多哲学就足够了……让我们来看看控件代码。
如何使用此控件
应用程序从一个演示表单开始。您将浏览并选择您选择的 .NET DLL 程序集或随此代码示例提供的程序集。
您可以从列表框中选择程序集的数据类型,然后单击“创建”。它将创建该数据类型的实例以及一个对象表单,供您编辑其字段。
与任何对话框表单一样,您将进行修改并通过单击“确定”保存它们。您可以单击“编辑”以验证您的更改是否仍然在应用程序中。
或者,您可以从列表框中选择程序集的数据类型,然后单击“创建数组”。您可以创建多个选定类型对象并将它们添加到列表中。您可以单击“编辑数组”以从演示表单修改此列表。
代码和设计
有两个主要的 User Control 类(ComplexType
和 ComplexTypeArray
),它们提供了通用对象编辑控件的大部分功能。让我们从探索 ComplexType
的构造函数开始。
public ComplexType(Assembly assembly, Object instance, Control parent, bool bProperty)
{
this.parent = parent;
this.instance = instance;
this.clientAssembly = assembly;
this.isProperty = bProperty;
InitializeComponent();
if(isProperty)
AddPropertyControls(this.instance.GetType(), this.panel1);
else
AddFieldControls(this.instance.GetType(), this.panel1);
}
我必须克服的主要设计难题是允许任意数量的对象以及对象内部的对象的深度可以扩展和折叠到任何程度,只要我们在程序集(.NET DLL)中定义了它。在我的示例代码中,您会注意到我有一个 Employee
数据类型引用其自身类型,使其成为扩展控件到任何深度的良好示例。
您会注意到有两个主要函数被调用,分别是 AddPropertyControl
和 AddFieldControl
。顾名思义,字段可以是数据类型的公共和私有成员变量,而属性通常是公共的。
public void AddFieldControls(Type moduleType, Panel panl)
{
FieldInfo[] fields = moduleType.GetFields(BindingFlags.Instance |
BindingFlags.Public | BindingFlags.NonPublic);
//true for if moduleType is enum,int,string,bool,double etc
if (IsBasicType(moduleType))
{
//create basic controls
}else{
foreach (FieldInfo fieldInfo in fields)
{
//create controls for each field type
}
}
}