65.9K
CodeProject 正在变化。 阅读更多。
Home

使用反射在运行时获取控件属性

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.86/5 (28投票s)

2007年2月27日

CPOL

4分钟阅读

viewsIcon

125343

downloadIcon

999

.NET 中轻松访问控件属性

引言

Control 类是 .NET Framework 提供的一个非常重要的类,它位于 System.Componentmodel.Component 命名空间下。无论您使用的是WindowsWeb 还是移动应用程序,都会用到这个类。

我们都知道,在设计时和编译时很容易访问所有控件的属性。但是,在运行时获取某些控件的属性会涉及到一些复杂性。

Control 类派生出了不同类型的控件,例如 WebControlsMobileControls,它们具有一些共同的属性和属性类型。在 Control 类中,有几个控件共享字符串属性 "Text",并且大多数窗体控件以基本相同的方式使用此属性。它用于获取和设置用户输入的数据。还有其他一些通用的属性和属性类型被各种控件使用。

在本文中,我们将讨论如何通过编程方式使用反射,仅用一行代码在运行时访问重要的控件属性,例如 "Text" 属性,从而减少代码行数并提高可读性(这里我们只讨论单个属性 "Text")。

使用此技术,您可以将逻辑扩展到运行时任何控件的任何数量的属性,而不管控件的类型如何。通过这样做,您还可以使用户能够动态地获取或设置控件的任何属性值。

使用 System.Reflection

反射是在运行时读取元数据的能力。使用反射,可以动态地发现类型的成员(方法、属性和事件)并调用它们。在 .NET Framework 中,编译器在编译期间会生成元数据,并将元数据(以二进制格式)存储在程序集和模块中。

System.Type 类是反射中的主要类。它表示类型声明(类类型、接口类型、数组类型、值类型和枚举类型)。System.Type 也是访问元数据的主要入口点。它提供了获取类型声明信息的方法,例如构造函数、属性、方法和事件。Propertyinfo 类是 System.Type 的一个对象,此方法返回一个 PropertyInfo 类型对象的数组,该类属于 System.Reflection 命名空间。

示例

在下面的 Web 窗体中,我们将使用一些标准控件并在设计页面时设置所需的属性,在本例中是一个 Label、一个 Textbox 和一个 Button。我们将编写代码,以便能够访问运行时属性。

Screenshot - VICTOR.jpg

protected void Button1_Click1(object sender, EventArgs e) 

{ 

DisplyDetails(this); 

} 

In the above code, we invoke the DisplyDetails() method passing the object of control class by "this" reference object in Button Click event handler. 

private void DisplyDetails(Control control) 

{ 

foreach (Control controls in this.form1.Controls) 

{ 

string controlId = controls.ID; 

Response.Write(controlId); 

Response.Write("<br>"); 

Type controlType = controls.GetType(); 

PropertyInfo[] properties = controlType.GetProperties(); 

foreach (PropertyInfo controlProperty in properties) 

{ 

if (controlProperty.Name == "Text" && 

controlProperty.PropertyType == typeof(String)) 

{ 

string propertyValue = GetPropertyValue(controlProperty.Name, controls); 

Response.Write(propertyValue); 

Response.Write("<br><br>"); 

} 

} 

} 

}

在上面的代码中,我们有一个 ControlCollection 对象,它表示 UI 层次结构中特定服务器控件的子控件。使用 for each 循环,我们检查 ASP.NET 控件的 Controlcollection 对象并获取 ID 属性。我们获取控件对象的 Type,并使用该 Type 获取一个 PropertyInfo 对象数组。每个 PropertyInfo 对象都包含有关我们的控件对象属性的信息,以及从控件对象获取和设置值的能力。

通过调用 GetProperties 方法,我们获得一个 PropertyInfo 对象数组。PropertyInfo 类为数组中的每个对象提供名称和属性类型。我们将遍历 PropertyInfo 数组,查找名为 "Text" 的 String 属性。如果控件具有该属性,我们将调用 GetPropertyValue() 方法,并将属性名称和控件类对象作为两个参数传递。获取属性值的代码如下所示。

private string GetPropertyValue(string pName, Control control) 

{ 

Type type = control.GetType(); 

string propertyName = pName; 

BindingFlags flags = BindingFlags.GetProperty; 

Binder binder = null; 

object[] args = null; 

object value = type.InvokeMember( 

propertyName, 

flags, 

binder, 

control, 

args 

); 

return value.ToString(); 

}

在上面的代码中,我们有属性名称和控件类对象,我们将使用它们来获取对象的类型。类型对象具有 InvokeMethod() 方法,可用于调用类型对象所描述类的成员。InvokeMember() 有重载,上面的版本接受五个参数,如下所示。

PropertyNamePropertyName 是您希望调用的方法或属性的名称。

Flags:是 BindingFlags 的位掩码,用于指定如何进行对象搜索。在这种情况下,我们将使用 GetProperty 标志。这些是动态调用方法的标准标志。

Binder:Binder 用于辅助类型转换。通过传递 null,我们将指定我们想要默认的 binder。

ControlControl 是运行时将尝试在其上调用成员的对象,因此我们传递对所选控件的引用。

Args:一个要传递给我们要调用的成员的参数数组。由于获取属性不需要任何参数,因此我们可以传递 null 值。

调用此方法的结果被分配给局部变量 "value",然后该值作为字符串返回到 DispalyDetails() 方法,在那里显示。

此代码适用于所有标准的 .NET 控件以及第三方控件,前提是该控件已从控件类派生并且包含所需的属性。

© . All rights reserved.