Practical Applications of Reflection

A common and practical application ”binding properties to controls ”uses Reflection behind the scenes. This works in Windows Forms and Web pages.

DataBinding.sln contains an example of user -defined type Customer and a place to store customers as well as a Contacts class that can contain an ArrayList of contacts. The ArrayList implements an interface called IList , which supports enumeration that allows us to bind controls directly to our objects. The sample application is shown in Figure 4.1.

Figure 4.1. A simple form bound directly to the shown TextBox controls by using Reflection and DataBindings .

graphics/04fig01.gif

The Customer class contains two properties, Name and WebSite (as shown in the figure). The Contacts class contains an ArrayList field and a ReadOnly ArrayList property named Items . Here is the implementation of the Contacts.Items property.

 Public ReadOnly Property Items() As ArrayList   Get     If (FItems Is Nothing) Then FItems = New ArrayList()     Return FItems   End Get End Property 

NOTE

The Items property employs a strategy known as lazy instantiation . Lazy instantiation allows us to defer object creation until we need it. The spin-up time for classes is reduced by the cost of the lazy object, and we are sure that the object is created only when it is absolutely requested . In the preceding fragment, the ArrayList is created on first request.

The property uses the ReadOnly modifier, which means we can and will implement only a property getter. We will bind to the Contacts.Items property.

To bind one of the TextBox controls to a specific property of our customer ”aside from adding customers to a Contacts object ”we need to determine which property of the TextBox we are binding to and which property of Customer we will get the data from. TextBox.Text is an appropriate property of the TextBox to bind to, and it is reasonable to bind the Customer.Name property to that. Here is the single line of code needed to accomplish this.

 TextBox1.DataBindings.Add("Text", FContacts.Items, "Name") 

Assuming we have an instance of Contacts named FContacts , we invoke the TextBox1.DataBindings.Add method. The first argument represents the TextBox property to bind to. The second argument is our data source; it's pretty cool that we can bind right to our Contacts.Items collection. The third property is the name of the field in the Contacts.Items data source that we want to get data from. Literally, now, TextBox1 is a data-bound control; it is bound to a Contacts object.

It is interesting to note that ArrayList does not have a property named Name . Name is discovered by Reflection against a single object in the ArrayList . We implicitly create a binding object by passing the necessary arguments to the overloaded Add method. (We can also manually construct a binding object and pass that to Add too.) Reflection is used to examine the type of the objects stored in the ArrayList and to bind to the elements of that type. In this instance the object is a Customer object.

NOTE

Unfortunately you usually have to bind to a homogeneous object. For example, you cannot add instances of a Person object and an instance of a Customer object to the same ArrayList . The ArrayList must contain all of one type.

However, you can bind to heterogeneous types as long as all types have the same ancestry. For example, if you define a Person class and a Customer class where Customer generalizes Person , you can add both Customer objects and Person objects to the same ArrayList and the binding will still work.

To make navigation automatic, implement an event handler for the buttons and change the position of the BindingContext associated with a particular control. For example, to implement forward navigation, increment the Position property of the BindingManagerBase object. In the following statement, TextBox1.BindingContext.Item returns a BindingManagerBase object.

 TextBox1.BindingContext.Item(FContacts.Items).Position += 1 

Incrementing the Position property of the BindingManagerBase will safely navigate to the next element in the collection. If all the controls on a form are bound to the same data source, you need to change the position of only one to update all. Decrement the position to move backward. The BindingManagerBase will not allow you to increment or decrement outside of the range of elements.

One of the benefits of an object-oriented framework is generalization and reuse. By generalizing how controls are bound, we have greater flexibility with what we bind to. Of course, we can bind to an ADO.NET DataSet object, or we can bind directly to collections of objects as demonstrated.



Visual Basic. NET Power Coding
Visual Basic(R) .NET Power Coding
ISBN: 0672324075
EAN: 2147483647
Year: 2005
Pages: 215
Authors: Paul Kimmel

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net