What we have examined so far is the most
common form of data binding that involves list and iterative controls
and collections of data. It is important to note that any of the
ASP.NET controls support some minimal form of data binding, including
text boxes and labels, through the DataBind
method. In its simplest form, a binding is a connection between one
piece of data and a server control property. This simple form of
binding is established through a special expression that gets evaluated
when the code in the page calls the DataBind method on the control.
1. Simple Data Binding
A data-binding expression is any executable code wrapped by <% ... %>
and prefixed by the symbol #. Typically, you use data-binding
expressions to set the value of an attribute in the opening tag of a
server control. A data-binding expression is programmatically managed
via an instance of the DataBoundLiteralControl class.
Note
The
binding expression is really any executable code that can be evaluated
at run time. Its purpose is to generate data that the control can use
to bind for display or editing. Typically, the code retrieves data from
the data source, but there is no requirement that this be the case. Any
executable code is acceptable so long as it returns data for binding. A
data-binding expression is evaluated only when something happens that
fires the control’s DataBinding event. |
The following code snippet shows how to set the text of a label with the current time:
<asp:label runat="server" Text='<%# DateTime.Now %>' />
Within the delimiters, you
can invoke user-defined page methods, static methods, and properties
and methods of any other page component. The following code
demonstrates a label bound to the name of the currently selected
element in a drop-down list control:
<asp:label runat="server" Text='<%# dropdown.SelectedItem.Text %>' />
Note that if you’re going to
use quotes within the expression, you should wrap the expression itself
with single quotes. The data-binding expression can accept a minimal
set of operators, mostly for concatenating subexpressions. If you need
more advanced processing and use external arguments, resort to a
user-defined method. The only requirement is that the method is
declared public or protected.
Important
Any data-bound expression you define in the page is evaluated only after DataBind is called. You can either call DataBind on the page object or on the specific control. If you call DataBind on the page object, it will recursively call DataBind on all controls defined in the page. If DataBind is not called, no <%# ...%> expressions will ever be evaluated. |
Binding in Action
Data-binding
expressions are particularly useful to update, in a pure declarative
manner, properties of controls that depend on other controls in the
same page. For example, suppose you have a drop-down list of colors and
a label and that you want the text of the label to reflect the selected
color.
<asp:DropDownList ID="SelColors" runat="server" AutoPostBack="True">
<asp:ListItem>Orange</asp:ListItem>
<asp:ListItem>Green</asp:ListItem>
<asp:ListItem>Red</asp:ListItem>
<asp:ListItem>Blue</asp:ListItem>
</asp:DropDownList>
<asp:Label runat="server" ID="lblColor"
Text='<%# "<b>You selected: </b>" + SelColors.SelectedValue %>' />
Note that in the <%# ... %>
expression you can use any combination of methods, constants, and
properties as long as the final result matches the type of the bound
property. Also note that the evaluation of the expression requires a
postback and a call to DataBind. We set the AutoPostBack property to true just to force a postback when the selection changes in the drop-down list. At the same time, a call to the page’s or label’s DataBind method is required for the refresh to occur.
protected void Page_Load(object sender, EventArgs e)
{
DataBind();
}
You can bind to expressions virtually any control properties regardless of the type. Let’s see how to bind the ForeColor property of the Label control to the color string picked from the drop-down list:
ForeColor='<%# Color.FromName(SelColors.SelectedValue) %>'
Note that you can’t just set ForeColor to an expression that evaluates to a color string, such as “orange”.
ForeColor='<%# SelColors.SelectedValue %>'
The preceding code won’t
compile because of the impossible automatic conversion between a string
(your expression) and a color (the type of the ForeColor property). Interestingly enough, of the following statements only the second will work fine:
ForeColor='<%# "orange" %>'
ForeColor="orange"
The upshot is that a
data-binding expression requires that the return type match the type of
the property represented via an attribute. Using a plain constant
string is fine, on the other hand, because the page parser recognizes
the expression and seamlessly inserts proper conversion code, if such a
conversion is possible. Figure 1 shows the sample page in action.
Implementation of Data-Binding Expressions
What
really happens when a data-binding expression is found in a Web page?
How does the ASP.NET runtime process it? Let’s consider the following
code:
<asp:label runat="server" id="today" text='<%# DateTime.Now %>' />
When the page parser takes care of the .aspx
source code, it generates a class where each server control has a
factory method. The factory method simply maps the tag name to a
server-side control class and transforms attributes on the tag into
property assignments. In addition, if a data-binding expression is
found, the parser adds a handler for the DataBinding event of the control—a Label in this case. Here’s some pseudocode to illustrate the point:
private Control __BuildControlToday() {
Label __ctrl = new Label();
this.today = __ctrl;
__ctrl.ID = "today";
__ctrl.DataBinding += new EventHandler(this.__DataBindToday);
return __ctrl;
}
The handler assigns the data-binding expression verbatim to the property:
public void __DataBindToday(object sender, EventArgs e) {
Label target;
target = (Label) sender;
target.Text = Convert.ToString(DateTime.Now);
}
If
the value returned by the data-binding expression doesn’t match the
expected type, you generally get a compile error. However, if the
expected type is string, the parser attempts a standard conversion through the Convert.ToString method. (All .NET Framework types are convertible to a string because they inherit the ToString method from the root object type.)