Although using simple data
binding is optional, repeated-value binding is so useful that almost
every ASP.NET application will want to use it somewhere.
Repeated-value data binding
works with the ASP.NET list controls . To use repeated-value binding, you link
one of these controls to a data source (such as a field in a data
table). When you call DataBind(), the control automatically creates a
full list using all the corresponding values. This saves you from
writing code that loops through the array or data table and manually
adds elements to a control. Repeated-value binding can also simplify
your life by supporting advanced formatting and template options that
automatically configure how the data should look when it's placed in the
control.
To create a data
expression for list binding, you need to use a list control that
explicitly supports data binding. Luckily, ASP.NET provides a number of
list controls, many of which you've probably already used in other
applications or examples:
ListBox, DropDownList, CheckBoxList, and RadioButtonList:
These web controls provide a list for a single field of information.
HtmlSelect:
This server-side HTML
control represents the HTML <select> element and works essentially
the same way as the ListBox web control. Generally, you'll use this
control only for backward compatibility.
GridView, DetailsView, FormView, and ListView:
These rich web
controls allow you to provide repeating lists or grids that can display
more than one field of information at a time. For example, if you bind
one of these controls to a full-fledged table in a DataSet, you can
display the values from multiple fields. These controls offer the most
powerful and flexible options for data binding.
With repeated-value data
binding, you can write a data binding expression in your .aspx file, or
you can apply the data binding by setting control properties. In the
case of the simpler list controls, you'll usually just set properties.
Of course, you can set properties in many ways, such as by using code in
a code-behind file or by modifying the control tag in the .aspx file,
possibly with the help of Visual Studio's Properties window. The
approach you take doesn't matter. The important detail is that with the
simple list controls, you don't use any <%# expression %> data
binding expressions.
To continue any further
with data binding, it will help to divide the subject into a few basic
categories. You'll start by looking at data binding with the list
controls.
1. Data Binding with Simple List Controls
In some ways, data binding to a list control is the simplest kind of data binding. You need to follow only three steps:
Create
and fill some kind of data object. You have numerous options, including
an array, the basic ArrayList and Hashtable collections, the strongly
typed List and Dictionary collections, and the DataTable and DataSet
objects. Essentially, you can use any type of collection that supports
the IEnumerable interface, although you'll discover each class has
specific advantages and disadvantages.
Link
the object to the appropriate control. To do this, you need to set only
a couple of properties, including DataSource. If you're binding to a
full DataSet, you'll also need to set the DataMember property to
identify the appropriate table you want to use.
Activate
the binding. As with single-value binding, you activate data binding by
using the DataBind() method, either for the specific control or for all
contained controls at once by using the DataBind() method for the
current page.
This process is the same
whether you're using the ListBox, the DropDownList, the CheckBoxList,
the RadioButtonList, or even the HtmlSelect control. All these controls
provide the same properties and work the same way. The only difference
is in the way they appear on the final web page.
2. A Simple List Binding Example
To try this type of data
binding, add a ListBox control to a new web page. Next, import the
System.Collections namespace in your code. Finally, use the Page.Load
event handler to create an ArrayList collection to use as a data source
as follows:
Dim fruit As New ArrayList()
fruit.Add("Kiwi")
fruit.Add("Pear")
fruit.Add("Mango")
fruit.Add("Blueberry")
fruit.Add("Apricot")
fruit.Add("Banana")
fruit.Add("Peach")
fruit.Add("Plum")
Now, you can link this collection to the ListBox control:
lstItems.DataSource = fruit
Because an ArrayList is a
straightforward, unstructured type of object, this is all the
information you need to set. If you were using a DataTable (which has
more than one field) or a DataSet (which has more than one DataTable),
you would have to specify additional information.
To activate the binding, use the DataBind() method:
Me.DataBind()
You could also use lstItems.DataBind() to bind just the ListBox control. Figure 1 shows the resulting web page.
This technique can save quite a
few lines of code. This example doesn't offer a lot of savings because
the collection is created just before it's displayed. In a more
realistic application, however, you might be using a function that
returns a ready-made collection to you:
Dim fruit As ArrayList
fruit = GetFruitsInSeason("Summer")
In this case, it's extremely simple to add the extra two lines needed to bind and display the collection in the window:
lstItems.DataSource = fruit
Me.DataBind()
or you could even change it to the following, even more compact, code:
lstItems.DataSource = GetFruitsInSeason("Summer")
Me.DataBind()
On the other hand,
consider the extra trouble you would have to go through if you didn't
use data binding. This type of savings compounds rapidly, especially
when you start combining data binding with multiple controls, advanced
objects such as DataSets, or advanced controls that apply formatting
through templates.
3. Strongly Typed Collections
You can use data binding
with the Hashtable and ArrayList, two of the more useful collection
classes in the System.Collections namespace. .NET includes a more stringent set of collections in another namespace:
System.Collections.Generic. These collections are ideal in cases where
you want your collection to hold just a single type of object (for
example, just strings). When you use the generic collections, you choose
the item type you want to use, and the collection object is "locked in"
to your choice (which is similar to how an array works). This means if
you try to add another type of object that doesn't belong in the
collection, you'll get a compile-time error. Similarly, when you pull an
item out of the collection, you don't need to write casting code to
convert it to the right type, because the compiler already knows what
type of objects you're using. This behavior is safer and more
convenient, and it's what you'll want most of the time.
To use a generic collection, you must import the right namespace:
Imports System.Collections.Generic
The generic version of the
ArrayList class is named List. Here's how you create a List collection
object that can only store strings:
Dim fruit As New List(Of String)()
fruit.Add("Kiwi")
fruit.Add("Pear")
The only real difference is that you need to specify the type of data you want to use when you declare the List object.
4. Multiple Binding
You can bind the same data
list object to multiple different controls. Consider the following
example, which compares all the types of list controls at your disposal
by loading them with the same information:
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As EventArgs) Handles Me.Load
' Create and fill the collection.
Dim fruit As New List(Of String)()
fruit.Add("Kiwi")
fruit.Add("Pear")
fruit.Add("Mango")
fruit.Add("Blueberry")
fruit.Add("Apricot")
fruit.Add("Banana")
fruit.Add("Peach")
fruit.Add("Plum")
' Define the binding for the list controls.
MyListBox.DataSource = fruit
MyDropDownListBox.DataSource = fruit
MyHtmlSelect.DataSource = fruit
MyCheckBoxList.DataSource = fruit
MyRadioButtonList.DataSource = fruit
' Activate the binding.
Me.DataBind()
End Sub
Figure 2 shows the rendered page.
This is another area where
ASP.NET data binding may differ from what you have experienced in a
desktop application. In traditional data binding, all the different
controls are sometimes treated like "views" on the same data source, and
you can work with only one record from the data source at a time. In
this type of data binding, when you select Pear in one list control, the
other list controls automatically refresh so that they too have Pear
selected (or the corresponding information from the same row). This
isn't how ASP.NET uses data binding. If you want this sort of effect,
you need to write custom code to pull it off.
5. Data Binding with a Dictionary Collection
A dictionary collection is a special kind of collection in which every item (or definition, to use the dictionary analogy) is indexed with a specific key (or dictionary word). This is similar to the way that built-in ASP.NET collections such as Session, Application, and Cache work.
Dictionary collections always
need keys. This makes it easier to retrieve the item you want. In
ordinary collections, like the ArrayList or List, you need to find the
item you want by its index number position, or—more often—by traveling
through the whole collection until you come across the right item. With a
dictionary collection, you retrieve the item you want using its key.
Generally, ordinary collections make sense when you need to work with
all the items at once, while dictionary collections make sense when you
frequently retrieve a single specific item.
You can use two basic
dictionary-style collections in .NET. The Hashtable collection (in the
System.Collections namespace) allows you to store any type of object and
use any type of object for the key values. The Dictionary collection
(in the System.Collections.Generic namespace) uses generics to provide
the same "locking in" behavior as the List collection. You choose the
item type and the key type upfront to prevent errors and reduce the
amount of casting code you need to write.
The following example
uses the Dictionary collection class, which it creates once—the first
time the page is requested. You create a Dictionary object in much the
same way you create an ArrayList or List collection. The only difference
is that you need to supply a unique key for every item. This example
uses the lazy practice of assigning a sequential number for each key:
Protected Sub Page_Load(ByVal sender As Object, _
ByVal e As EventArgs) Handles Me.Load
If Not Me.IsPostBack
' Use integers to index each item. Each item is a string.
Dim fruit As New Dictionary(Of Integer, String)()
fruit.Add(1, "Kiwi")
fruit.Add(2, "Pear")
fruit.Add(3, "Mango")
fruit.Add(4, "Blueberry")
fruit.Add(5, "Apricot")
fruit.Add(6, "Banana")
fruit.Add(7, "Peach")
fruit.Add(8, "Plum")
' Define the binding for the list controls.
MyListBox.DataSource = fruit
' Choose what you want to display in the list.
MyListBox.DataTextField = "Value"
' Activate the binding.
Me.DataBind()
End If
End Sub
There's one new detail here. It's this line:
MyListBox.DataTextField = "Value"
Each item in a dictionary-style
collection has both a key and a value associated with it. If you don't
specify which property you want to display, ASP.NET simply calls the
ToString() method on each collection item. This may or may not produce
the result you want. However, by inserting this line of code, you
control exactly what appears in the list. The page will now appear as
expected, with all the fruit names.
NOTE
Notice that you need
to enclose the property name in quotation marks. ASP.NET uses reflection
to inspect your object and find the property that has the name Value at
runtime.
You
might want to experiment with what other types of collections you can
bind to a list control. One interesting option is to use a built-in
ASP.NET control such as the Session object. An item in the list will be
created for every currently defined Session variable, making this trick a
nice little debugging tool to quickly check current session
information.