Back in the days of Visual Basic, data binding was a clunky outcast programming technique. DAO’s simplistic and slow data controls gave data binding a bad name, and many seasoned developers didn’t use it at all. The prevailing thinking seemed to be, “Real programmers don’t eat quiche, and they certainly don’t data bind!”
With .NET, quite a few things have changed, one being the efficacy of binding controls to data sources for rapid application development. In fact, .NET moves the whole concept of data binding beyond simply attaching a control to a database table. This ability is particularly useful for ASP.NET developers, as it provides them with still more insulation from the vagaries of their application’s data access layer.
Data binding 101: DataSets
In its simplest form, data binding involves attaching an ASP.NET Web control, say a ListBox, to a DataSet containing some database data. The ListBox.DataSource property lets you specify the DataSet to which the control should bind, and the DataBind method actually fills the control with data. Because a DataSet can contain multiple fields, Web controls with a single column (ListBox, DropDownList, etc.) all expose DataTextField and DataKeyField properties to let you specify the name of the field the control will display as text and use as a value, respectively.
Listing A contains a simple example that binds a ListBox to the Categories table of the Northwind sample database. After creating the DataSet, I bind it to ListBox1 using the DataSource property. I then set the DataTextField property to CategoryName, the field that ListBox1 should display (it will be used as SelectedItem.Text), and the DataKeyField property to CategoryId so that ListBox1 will use it as the key. (It will be returned as SelectedItem.Value.).
Data binding 201: Arrays and collections
Okay, so binding to a DataSet is child’s play. But what if the data you want isn’t contained in a database? What if you would like to allow the user to choose from an array of objects? Sure, you could manually create a DataSet containing the data, but that's kind of like building a mansion when all you need is a tool shed. Wouldn’t it be nice if you could just bind directly to the array?
As it turns out, you can bind directly to an array of reference-type variables, as you can see from Listing B. In this case, I have a class, DataClass, that exposes two properties, Description and ID. I can create an array of DataClass objects and bind it to ListBox1 much as I did with the DataSet in Listing A, setting DataTextField to Description and DataKeyField to ID.
ASP.NET uses the Reflection API at runtime to examine the objects in the array and find the appropriate properties, which it then loads into ListBox1’s ListItemCollection. Note that ASP.NET specifically looks for property members—public variables or function methods won’t work here.
Listing C illustrates that collections work just as well, which shouldn’t really surprise you, since by now I’m sure you know all about how .NET uses the IEnumerable and IEnumerator interfaces to iterate over collections. If you by some chance don’t know what I’m talking about, try looking over Listing D, where ListBox1 binds to CollectionClass, which implements IEnumerable and IEnumerator to gain collection-like iteration capabilities.
Data binding 301: DataGrids
Data binding works similarly for DataGrids and related controls, except that you’ll probably be dealing with more than one column in the control—otherwise, why use a DataGrid? The default binding behavior for DataGrids is fairly intelligent: All columns (in the case of a DataSet) or public properties (for other objects) will be displayed. So just setting the DataSource property will give you a functional data bound grid.
Of course there are situations where you won’t want DataGrid to create columns for you. You can disable the default automatic column-generation behavior and take control of the creation and binding of the DataGrid’s columns by setting the AutoGenerateColumns property to false. You can then create columns for the grid either by using Visual Studio .NET’s column properties editor, shown in Figure A, or by creating an instance of System.Web.UI.WebControls.BoundColumn for each column the DataGrid should contain.
|Visual Studio .NET provides a nice column properties editor.|
Listing E rewrites the collection binding example from Listing C to work with a DataGrid. I first turn off automatic column generation in DataGrid1 and then create a new BoundColumn object. Using the DataField property, I bind the column object to the Description property of DataClass and then add it to DataGrid1’s column collection.
Not only is data binding a great way to speed application development, but it can also help hide the particulars of your data architecture from your application’s presentation layer. By using the same mechanism for binding to database and object data, Microsoft has made it much more practical to use data bound controls in an application.