CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Jeffrey Palermo (.com)

Blog moved to www.jeffreypalermo.com

Behavior of DataGrid.ItemDataBound and DataGrid.ItemCreated - level 200

When using the DataGrid control, one needs to know when to use the ItemDataBound event and when to use the ItemCreated event.  These event names are pretty easy to follow.  ItemCreated is when that row of the DataGrid is created.  The controls are there, but that's it.  On the ItemDataBound event, the controls are bound to their data, an dthe data is available for access.  If you have logic that depends on the bound data, use the ItemDataBound event, which fires after the ItemCreated event.

In my dealings with using an embedded control in the DataGrid header, I need to access this control after it is created.  I can access this control in either event since this control doesn't depend on data, so I elect to use the ItemDataBound event for this.  I have a button in my header, and I want to add a ServerClick event handler to it after it is created, so in the ItemDataBound event handler, I have to test the e.Item.ItemIndex.  The ItemDataBound event fires once for every row in the DataGrid.  The data-bound rows are 0-based, but for the header and footer, the ItemIndex is -1.  So if you have both the header and footer, then ItemIndex will be -1 twice.  For instance, to get the control in my header, I have to test for ItemIndex == -1, and then FindControl(”myButton”).  That will work for the header, but it will bomb later.  Why?

Because ItemDataBound is fired twice with ItemIndex == -1.  First for the header, then 0,1,2,3,4, etc for the data-bound rows, and then -1 again for the Footer.  Since myButton isn't in the footer, I can't find it.  Ok, so now I know that -1 in ItemDataBound happens twice.  Knowing this, I can code against it.

What I would rather see is DataGrid.Header.Controls and DataGrid.Footer.Controls since the Header and Footer are both controls within the DataGrid.  This would be a simpler API.

Just remember when embedding controls in your header or footer that the ItemIndex will be -1 when you access these controls in the ItemCreated or ItemDataBound event handlers.



Comments

Famil Jones said:

ListItemType Enumeration could also be used to test if the item type is header or footer in ItemDataBound and ItemCreated events (eg. If e.Item.ItemType = ListItemType.Header Then ... End If).
# July 28, 2004 4:35 AM

Abner Mendoza said:

Instead of using the ItemIndex, it would probably be easier to use ItemType. So in your event handler you can have a statement to test for e.Item.ItemType and then your header would be = ListItemType.Header and your footer would be = ListItemType.Footer.

# July 28, 2004 4:35 AM

Jeffrey Palermo said:

Those are great comments!! I will, in fact, use the ItemType property. That is a little more readable than testing the ItemIndex. That is great for accessing embedded controls during the data-binding events. I also have to access the button in the Header at other times, and I can't iterate through the Items collection because the Header isn't an item, so I'm accessing my embedded button by calling DataGrid.Controls[0].Controls[0].FindControl("myButton"). The first control in DataGrid is an HtmlTable, and then it has a collection of HtmlTableRow, so I have to get the table, then Controls[0] of the table, which is the first row, and then do a FindControl(). If I find a more intuitive way to do this, I'll post it.
# July 28, 2004 5:47 AM

sa said:

as
# August 2, 2004 1:41 AM

Kostas said:

Hello Jeffrey

I use the ItemDataBound method to populate a column in my datagrid like this

private void DataGrid1_ItemDataBound (object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
if (e.Item.DataItem is Employee)
{
Employee currentEmployee = ((Employee)(e.Item.DataItem));
e.Item.Cells[0].Text = string.Format("{0:D3}",currentEmployee.EID);
}
}

But i see no results..any suggestions?
# October 11, 2004 8:26 AM

Richard Myers said:

Hello,
Another point to make about the itemcreated vrs itemdatabound events is that assuming the data is bound on the first load of the page the item databound event will not occur OnPostBack. This is becuase the data is being drawn from ViewState and is therefore already bound.

This is an essential difference if you wish to cancel out of a page via a cancel button etc.

Otherwise via the ItemCreated event you may find your code throwing errors as it encounters null valued variables and the like within the event.

# November 10, 2004 3:55 PM

Pyrenus said:

Wow this is old, anyways, I had this problem and just now figured it out, wanted to post my results in case someone else was searching and had this problem.

I have a checkbox in the header of my datagrid and I was trying to get the value back out of it in my code.

Controls(0).Controls(0).FindControl("CheckBoxName") was not working for me.

I ended up printing out a ton of debugging code to figure it out, but for me, I had to use:

Controls(0).Controls(1).FindControl(...)

Not sure why, but that's where I found my control.

# February 6, 2007 2:52 PM

Lavkush said:

how to change the color of that row in the click of linkbutton in the datagrid

# May 29, 2007 10:03 AM

About Jeffrey Palermo

Jeffrey Palermo is a software management consultant and the CTO of Headspring Systems in Austin, TX. Jeffrey specializes in Agile coaching and helps companies double the productivity of software teams. Jeffrey is an MCSD.Net , Microsoft MVP, Certified Scrummaster, Austin .Net User Group leader, AgileAustin board member, INETA speaker, INETA Membership Mentor, Christian, husband, father, motorcyclist, Eagle Scout, U.S. Army Veteran, and Texas A&M University graduate. Check out Devlicio.us!

Our Sponsors

This Blog

Syndication

News

Headspring Systems

View Jeffrey Palermo's profile on LinkedIn

See my new blog at .jeffreypalermo.com