Introduction
Control
class is very important class provided by the .NET Framework that is present in namespace System.Componentmodel.Component
. In all applications you utilize this class regardless of either it being Windows, Web or a Mobile Application.
As we all knew that it's easy to access all the control properties during design time as well as during compile time. But getting a few control properties at runtime involves some complexity.
There are different types of controls derived from Control
class such as WebControls, MobileControls
that have some common properties and property types. In Control
class several controls share the String
property "Text
" and most form controls use this property in essentially the same way. It is used to get and set data that the user inputs. There are other common properties and property types used by a variety of controls.
In this article we will discuss how to access important control properties such as "Text" property at runtime by programmatically using Reflection with only a single line of code, resulting in fewer lines of code and increased readability (Here we will discuss only for single property "Text").
Using this technique you can expand your logic for different properties of any number of controls regardless of the type of the control at runtime. By doing this you can also enable the user to get or set values of any property of a control dynamically.
Using System. Reflection
Reflection is the ability to read metadata at runtime. Using reflection, it is possible to uncover the methods, properties, and events of a type, and to invoke them dynamically. In .NET Framework a compiler will generate metadata during compilation and stores the metadata (in a binary format) into assemblies and modules.
System.Type
class is the main class in Reflection. It represents type declarations (class types, interface types, array types, value types and enumeration types.) and also System.Type
is the primary gateway to metadata. It provides methods for obtaining information about a Type declaration, such as the constructors, properties, methods and Events. Propertyinfo
class is an object of System.Type
, this method returns an array of objects of type PropertyInfo
and this class is part of System.Reflection Namespace
.
Example
In the web form shown below, we will take some standard controls and set the properties as required while designing the page, in this case a Label, a Textbox and a Button. We will write the code so that we can be able to access the properties at runtime.
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>");
}
}
}
}
In the code above, we have ControlCollection
object that represents the child controls for a specified server control in the UI hierarchy. Using for each loop, we check the Controlcollection
object for ASP.NET controls and gets the ID property. We get the Type of our control object and use that Type to get an array of PropertyInfo
objects. Each PropertyInfo
object contains information about our control object properties as well as the ability to get and set values from the control object.
By invoking the GetProperties
method we obtain an array of PropertyInfo
objects. The PropertyInfo
class gives each object in the array, in this case name property and property type. We'll iterate through the PropertyInfo
array and look for a String
property called "Text". If the control has that property, we'll invoke a method GetPropertyValue()
passing property name and control class object as the two arguments. The code to get property values is illustrated below.
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();
}
In the code above, we have property name and control class object using which we will get the type of the object. The type object has method InvokeMethod()
, which can be used to invoke a member of class described by the type object. The InvokeMember()
has overloads, the above version will takes five arguments, which are given below.
PropertyName
: PropertyName
is the name of the method or property you wish to invoke.
Flags
: Is a bit mask of BindingFlags
that specify how the search of the object is conducted. In this case we will use the GetProperty
flag. These are the standard flags for invoking a method dynamically.
Binder
: Binder is used to assist in type conversions. By passing in null, we will specify that we want the default binder.
Control
: Control
is the object the runtime will try to invoke the member upon, so we pass the reference to the selected control.
Args
: An array of arguments to pass to the member we're invoking. Since fetching a property does not require any parameters therefore we can pass a null value.
The result of invoking this method is assigned to the local variable "value", which is then returned as a string, to the DispalyDetails()
method, where it gets displayed.
This code will work for all standard .NET controls and also for third party controls provided the control has been derived from the control class as well as it contains required property.