Understanding the ItemDataBound Event
The ItemDataBound event in the ASP.NET DataGrid control fires whenever a row of data is bound to the grid. Think of it as a callback that hands you a snapshot of the row just before it appears on the page. The event handler receives two arguments: the source object – which is the grid itself – and a DataGridItemEventArgs instance. That instance contains a reference to the DataGridItem that is currently being processed, giving you access to the row’s cells, its data source object, and its type (header, footer, item, alternating item, etc.). Once the handler exits, that snapshot disappears; you must capture or store any values you need before the method ends.
Hooking the event is straightforward. In the markup of your .aspx page, add the OnItemDataBound attribute to the asp:DataGrid declaration and point it to the name of your method. For example:
When the page renders, the grid starts binding each row from its data source. As soon as a row is ready, the framework calls your ItemDataBoundHandler method. Inside that method you can inspect the row type, modify its appearance, alter cell values, or perform calculations that depend on the data in that row.
Because ItemDataBound is triggered for every row - including the header, footer, and separators - it’s a powerful place to implement row‑level logic. Common use cases include:
- Formatting cells based on values (e.g., turning negative numbers red).
- Aggregating totals or averages for a column and displaying them in the footer.
- Adding dynamic controls to a cell.
- Applying conditional CSS classes to alternate rows.
When you need to know whether the current item is a regular data row or a special row, you use the
ItemTypeproperty of theDataGridItem. TheListItemTypeenumeration lists all possible types:Header,Footer,Item,AlternatingItem,Separator,Pager, etc. A typical guard looks like:if (e.Item.ItemType == ListItemType.Footer) {</p> <p> // footer logic here</p> <p>}</p>Remember that
ItemDataBoundfires before the control renders to the browser, so any changes you make will be reflected in the final HTML. If you need to persist data across postbacks, store it in a session variable, hidden field, or a static variable, because the event’s context vanishes after execution.Performance considerations are minimal for most applications because the event executes quickly and only once per row. However, if your grid contains thousands of rows, keep your logic lean; heavy operations inside the handler can slow down rendering. In such scenarios, consider pre‑processing data in the code-behind or using a data view that already includes aggregates.
In summary, the
ItemDataBoundevent gives you a window into the binding process, letting you shape the final table on a per‑row basis. Mastering this event unlocks a range of dynamic behaviors that make your DataGrid both functional and visually appealing.Practical Example: Summing a Column in a DataGrid
Let’s walk through a concrete scenario: calculating the total of a price column and showing that total in the grid’s footer. This example illustrates how to set up a data source, bind it to a
DataGrid, and useItemDataBoundto accumulate values on the fly.First, create a
DataTablethat mimics a simple product catalog. We’ll define two columns:itemandprice. In the page’s code-behind, populate the table with a few sample rows. Notice that the table is declared as a protected field so that it can be reused across postbacks if necessary.protected DataTable dt = new DataTable("itemprice");</p> <p>dt.Columns.Add("item", typeof(string));</p> <p>dt.Columns.Add("price", typeof(float));</p> <p>DataRow dr;</p> <p>dr = dt.NewRow();</p> <p>dr["item"] = "pen";</p> <p>dr["price"] = 3.5f;</p> <p>dt.Rows.Add(dr);</p> <p>dr = dt.NewRow();</p> <p>dr["item"] = "camera";</p> <p>dr["price"] = 10.8f;</p> <p>dt.Rows.Add(dr);</p> <p>dr = dt.NewRow();</p> <p>dr["item"] = "coffee maker";</p> <p>dr["price"] = 40.2f;</p> <p>dt.Rows.Add(dr);</p> <p>// Bind the table to the grid</p> <p>dg.DataSource = dt.DefaultView;</p> <p>dg.DataBind();</p>When the grid renders, each row will show the item name and its price. To enable the footer, set the
ShowFooterproperty totruein the markup.The core of the example lies in the event handler. Declare a class‑level variable to hold the running total, initialize it to zero, and increment it each time a data row is processed. When the footer row arrives, place the accumulated total into its cell.
float total = 0f;</p> <p>protected void ItemDataBoundHandler(object sender, DataGridItemEventArgs e)</p> <p>{</p> <p> // Skip header and footer rows</p> <p> if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)</p> <p> {</p> <p> // Add the price from the second cell (index 1)</p> <p> total += float.Parse(e.Item.Cells[1].Text);</p> <p> e.Item.ForeColor = System.Drawing.Color.Blue; // optional styling</p> <p> }</p> <p> else if (e.Item.ItemType == ListItemType.Footer)</p> <p> {</p> <p> // Label the first cell and display the total in the second</p> <p> e.Item.Cells[0].Text = "Total";</p> <p> e.Item.Cells[1].Text = total.ToString("F2");</p> <p> }</p> <p>}</p>Notice how the handler uses
ListItemTypeto differentiate between regular data rows, the header, and the footer. Only regular rows contribute to the total. The footer receives the final value, formatted to two decimal places for clarity. Styling the row in blue demonstrates how you can alter appearance on the fly.When this code runs, the rendered table looks like this: a list of items, each priced individually, followed by a footer row labeled “Total” that displays the sum of all prices. The total calculation happens entirely in the server, so the client receives a ready‑to‑display table.
Why is this approach preferable to calculating the sum in a separate query or after binding? Because it eliminates the need for an additional pass over the data source. The
ItemDataBoundevent already gives you the data in context, so you can aggregate on the fly without duplicating work. Additionally, if the grid supports paging, the handler automatically adapts: each page shows its own subtotal in the footer, which can be useful for user readability.For larger data sets or more complex calculations, you might store intermediate totals in session or view state and combine them after the grid renders. However, for most use cases, the simple pattern shown above is efficient and easy to maintain.
Feel free to adapt this pattern for other types of aggregation - counts, averages, percentages - by tweaking the logic inside the
ItemDataBoundhandler. The event’s flexibility makes it a go-to tool for dynamic grid customization.Reference: MSDN Library – DataGridItemEventArgs (January 2004)





No comments yet. Be the first to comment!