ASP.NET Data Web Controls
Kick Start

Resources

Newsletter

About

FAQs
 
ASP.NET Data Web Controls Kick Start
Buy the Book!

5 Stars at Amazon.com!
5-Star Rating at Amazon.com!
Amazon.com ratings updated weekly...

Join WebHost4Life.com

Advertisements
Setting the SelectedIndex Programmatically
By: Scott Mitchell | Created: 2003-10-17 | Last Updated: 2003-10-17 | Printer-Friendly Version




Recently in a project I was working on I needed to be able to set the SelectedIndex of a DataList based on the values being bound to the DataList. Specifically, I had a DataList that utilized a SelectedItemTemplate like so:

<asp:DataList runat="server" id="myDataList"> <SelectedItemTemplate> <font size="+2"><b> <%# DataBinder.Eval(Container.DataItem, "SomeField") %> </b></font> ... </SelectedItemTemplate> <ItemTemplate> <%# DataBinder.Eval(Container.DataItem, "SomeOtherField") %> ... </ItemTemplate> </asp:DataList>

The ItemTemplate and SelectedItemTemplate were much more involved than the simple versions shown above, and differed from one another in a multitude of ways. When the page was visited, and the data was bound, I wanted a particular row made the selected row based on the data in the row. Imagine that the data I'm binding to the DataList is information about products in my product database. Perhaps passed in the QueryString to this page is a ProductID. I might want to make the item in the DataList that has the corresponding ProductID selected. In a similar vein, perhaps I want to have the cheapest, or most expensive, or newest product selected by default. How can I acheieve this functionality?

My first attempt was to create an event handler for the DataList's ItemDataBound event. Then, in this event handler I checked to see if whatever condition I was checking for was met, and, if it was, I set the DataList's SelectedIndex property to the ItemIndex of the item being processed. That is, my event handler looked like something like the following:

void myDataList_ItemDataBound(object sender, DataListItemEventArgs e) { // check to make sure we're dealing with an Item or AlternatingItem if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) { // check to see if some condition is true object di = e.Item.DataItem; int productID = Convert.ToInt32(DataBinder.Eval(di, "ProductID")); if (productID == Convert.ToInt32(Request.QueryString["ID"])) { // if the condition holds, set the DataList's SelectedIndex property myDataList.SelectedIndex = e.Item.ItemIndex; } } }
C#

 

While this code successfully sets the DataList's SelectedIndex, the specified item is not rendered using the SelectedItemTemplate. However, if the Web Form is posted back, by say a Button Web control click, then the item set in the ItemDataBound event handler is rendered with the SelectedItemIndex. What's going on here?

The problem lies in the order with which various events transpire in the creation of the DataList. Let's step through the series of events that transpire when the DataList's DataBind() method is called. For each item in the DataList's DataSource, the following things happen in this order:

  1. A DataListItem instance is created.
  2. The proper template is used to render the contents of the DataListItem. It's at this point that the DataList's SelectedIndex is checked to see whether the ItemTemplate should be used or if the SelectedItemTemplate should be used.
  3. The DataList's ItemCreated event is raised.
  4. The DataListItem's DataItem property is set to the current DataSource row, and the DataListItem's DataBind() method is called.
  5. The DataList's ItemDataBound event is raised.

By examining the above sequence of events, it hopefully is evident why we can't simply set the SelectedIndex property in the DataList's ItemDataBound event and have it work as planned. The reason is because the SelectedItemTemplate has already been applied several steps before the DataList's ItemDataBound event fires. So, if setting the SelectedIndex in the ItemDataBound event handler is too late, where can we set this property?

The answer is, before the DataList's DataBind() method is called! That is, we have to loop through the data that will be bound to the DataList prior to binding it to the DataList to determine the index of the piece of data we want to have be the selected index. Then, we need to set the DataList's SelectedIndex property to this discovered index value. Finally, we call the DataList's DataBind() method. With this approach, everything will work as desired since we are setting the DataList's SelectedIndex property before any of the steps outlined above transpire.

The following code demonstrates how to determine the index for the DataList's SelectedIndex property prior to binding the data to the DataList.

// We need to use a DataTable (or DataSet) because we need to // be able to loop through the records, searching for the record // that is the "selected record". A DataReader only allows one-way, // one-time forward access through the data, so DataReader's are not an // option here... // Create the connection and populate a DataTable SqlConnection myConnection = new SqlConnection(CONNECTION_STRING); SqlCommand myCommand = new SqlCommand(SQL_QUERY, myConnection); SqlDataAdapter myAdapter = new SqlDataAdapter(myCommand) DataTable dt = new DataTable(); myAdapter.Fill(dt); // Now, search through the DataTable, looking for the index of the // record that has the ProductID field equal to the ProductID // specified in the QueryString... for (int i = 0; i < dt.Rows.Count; i++) { if (Convert.ToInt32(dt.Rows[i]["ProductID"]) == Convert.ToInt32(Request.QueryString["ID"])) { // set the DataList's SelectedIndex property myDataList.SelectedIndex = i; break; // exit the for loop... } } // Now, bind the DataTable to the DataList myDataList.DataSource = dt; myDataList.DataBind();
C#

 

That's all there is to it! There's a live demo written in VB.NET that illustrates how this technique can be used to select the record from the DataTable that has a column with the maximum value among all records in the DataTable.

On a closing note, realize that the material in this FAQ focuses specifically on the DataList only, since the DataList is the only data Web control with a SelectedItemTemplate. However, this functionality can be applied to the templates of the other data Web controls in a similar fashion.

Happy Programming!


Home | FAQs | Articles | About | My Blog | Buy the Book!

Copyright 2006, Scott Mitchell. All Rights Reserved.