日期:2011-02-21  浏览次数:20504 次

ASP.NET offers a powerful way to render information from a database or XML file: Databinding. However, sometimes you need to be able to perform the databinding for almost all of the items in the data source. Or perhaps you have some special formatting or secondary data that you need to use with each row in the data source, so that you need a little finer control over how the data is bound to the control. In these cases, you will typically need to handle the onItemDataBound event, which is fired for each item as it is bound to your control. This gives you a LOT of flexibility, but unfortunately the code is a little bit hairy. Hopefully, having an example will help! First of all, let me explain that this example is taken from a LIVE application: my Regular Expression Library over at my ASP.NET training website, ASPSmith.com. You can see it in action by clicking here. You'll see what it is doing in a moment.

For my Regular Expression Library, I had several things I needed to adjust beyond the default databinding that my DataGrid provided "out-of-the-box". Firstly, I had a user_id field in my data that I wanted to convert to a link to a user's email. Next, I wanted to limit how much of the Description field was displayed on the search results page, to avoid causing the page to get excessively long (since the Description field is a TEXT field in my database, and could therefore be many megabytes long). Lastly, I had an Edit link that allowed the owner of the regular expression to edit it, but I didn't want that to be visible except if the current user was the owner of the expression. Let's see how this was done. First, let's take a look at my (rather lengthy) Datagrid declaration. The important part is listed in red.

default.aspx excerpt <asp:DataGrid id="dgRegexp" runat="server" AutoGenerateColumns="False" BorderColor="Black" BorderWidth="1" Style="margin-left:20px;" PageSize="5" AllowPaging="True" AllowCustomPaging="True" OnPageIndexChanged="dgRegexp_PageIndexChanged" onItemDataBound="dgRegexp_ItemDataBound" GridLines="Horizontal" PagerStyle-Mode="NumericPages" PagerStyle-HorizontalAlign="Center" PagerStyle-Position="TopAndBottom" PagerStyle-Width="100%" HeaderStyle-BackColor="#CC0000" HeaderStyle-Font-Bold="True" HeaderStyle-Font-Name="Verdana" HeaderStyle-Font-Size="9pt" HeaderStyle-ForeColor="White" ItemStyle-Font-Name="Arial" ItemStyle-Font-Size="8pt" AlternatingItemStyle-BackColor="#DDDDDD">  

This event, onItemDataBound, is supported by any control that supports data binding. You can use it with DataGrids, DataLists, Repeaters, etc. In this case, I have mapped mine to the "dgRegexp_ItemDataBound" event handler, which we'll take a look at now:

default.aspx excerpt protected void dgRegexp_ItemDataBound(Object Sender, DataGridItemEventArgs e)
{
// For Items and AlternatingItems,
// convert userid to email link
// truncate description
// hide edit link if not owner
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
Trace.Write("ItemDataBound",e.Item.DataItem.GetType().ToString());

int user_id = Int32.Parse(((System.Data.Common.DbDataRecord)e.Item.DataItem)["user_id"].ToString());
Trace.Write("ItemDataBound", "user_id: " + user_id.ToString());

ASPAlliance.DAL.UserDetails objUser = ASPAlliance.DAL.User.getUserDetails(user_id);
((System.Web.UI.WebControls.HyperLink)e.Item.FindControl("myuser")).Text =
objUser.first_name + " " + objUser.last_name + " (" + objUser.email + ")";
((System.Web.UI.WebControls.HyperLink)e.Item.FindControl("myuser")).NavigateUrl = "mailto:" + objUser.email;
Trace.Write("ItemDataBound", "myuser.Text: " + ((System.Web.UI.WebControls.HyperLink)e.Item.FindControl("myuser")).Text);

String desc = ((System.Data.Common.DbDataRecord)e.Item.DataItem)["description"].ToString();
if(desc.Length > 100)
{desc = desc.