Thursday, February 8, 2007

Formatting AutoGenerateColumns in an ASP.NET Grid

For a GridView: Trap the RowDataBound event
A GridView control exposes the RowDataBound event during the databinding process. A handler for this event is defined with the following signature:

RowDataBound_Handler(Object grid, GridViewRowEventArgs e)
{
}

The GridViewRowEventArgs object provides access to the table row that has just been bound through its Row property. Row is of the type GridViewRow, which is a derivative of TableRow. As such, there is a Cells property used to access individual TableCell objects.

In this example from the file formattingGridView.aspx in the article download (see the link at the top of the article), the assumption is made that the first column of data returned by a stored procedure (or other data source) is a text category of some kind. The remaining columns (potentially one or more) are values that need to be right-aligned, with alternating background colors on a column by column basis. To demonstrate conditional formatting for individual cells, a check is also made so special highlighting may be applied for high values. Just for fun, header cells are also styled in this code.

Collapse
private void GV_RowDataBound(object o, GridViewRowEventArgs e)
{
// apply custom formatting to data cells
if (e.Row.RowType == DataControlRowType.DataRow)
{
// set formatting for the category cell
TableCell cell = e.Row.Cells[0];
cell.Width = new Unit("120px");
cell.Style["border-right"] = "2px solid #666666";
cell.BackColor = System.Drawing.Color.LightGray;

// set formatting for value cells
for(int i=1; i {
cell = e.Row.Cells[i];

// right-align each of the column cells after the first
// and set the width
cell.HorizontalAlign = HorizontalAlign.Right;
cell.Width = new Unit("90px");

// alternate background colors
if (i % 2 == 1)
cell.BackColor
= System.Drawing.ColorTranslator.FromHtml("#EFEFEF");

// check value columns for a high enough value
// (value >= 8000) and apply special highlighting
if (GetCellValue(cell) >= 8000)
{
cell.Font.Bold = true;
cell.BorderWidth = new Unit("1px");
cell.BorderColor = System.Drawing.Color.Gray;
cell.BorderStyle = BorderStyle.Dotted;
cell.BackColor = System.Drawing.Color.Honeydew;
}

}
}

// apply custom formatting to the header cells
if (e.Row.RowType == DataControlRowType.Header)
{
foreach (TableCell cell in e.Row.Cells)
{
cell.Style["border-bottom"] = "2px solid #666666";
cell.BackColor=System.Drawing.Color.LightGray;
}
}

}

The event is then attached declaratively to the GridView by setting the OnRowDataBound attribute:

AutoGenerateColumns="true"
OnRowDataBound="GV_RowDataBound"
. . .
>


The code results in a grid that when rendered looks like the following:



For a DataGrid: Trap the ItemDataBound event
The technique for a DataGrid is similar. A DataGrid exposes the ItemDataBound event, which gives access to a DataGridItemEventArgs object. This object contains an Item property, with a Controls collection that is populated by TableCell objects during databinding. The following example from formattingDataGrid.aspx shows the same application of formatting as above but for a DataGrid:

Collapse
private void DG_ItemDataBound(object o, DataGridItemEventArgs e)
{
// apply custom formatting to data cells
if (e.Item.ItemType == ListItemType.Item
|| e.Item.ItemType == ListItemType.AlternatingItem)
{
// set formatting for the category cell
TableCell cell = (e.Item.Controls[0] as TableCell);
cell.Width = new Unit("120px");
cell.Style["border-right"] = "2px solid #666666";
cell.BackColor = System.Drawing.Color.LightGray;

// set formatting for value cells
for(int i=1; i {
cell = (e.Item.Controls[i] as TableCell);

// right-align each of the column cells after the first
// and set the width
cell.HorizontalAlign = HorizontalAlign.Right;
cell.Width = new Unit("90px");

// alternate background colors
if (i % 2 == 1)
cell.BackColor
= System.Drawing.ColorTranslator.FromHtml("#EFEFEF");

// check value columns for a high enough value
// (value >= 8000) and apply special highlighting
if (GetCellValue(cell) >= 8000)
{
cell.Font.Bold = true;
cell.BorderWidth = new Unit("1px");
cell.BorderColor = System.Drawing.Color.Gray;
cell.BorderStyle = BorderStyle.Dotted;
cell.BackColor = System.Drawing.Color.Honeydew;
}

}

}

// apply custom formatting to the header cells
if (e.Item.ItemType == ListItemType.Header)
{
foreach (TableCell cell in e.Item.Controls)
{
cell.Style["border-bottom"] = "2px solid #666666";
cell.BackColor=System.Drawing.Color.LightGray;
}
}

}

Similar to the GridView, the assignment of this event handler to the DataGrid is made declaratively by setting the OnItemDataBound attribute:

AutoGenerateColumns="true"
OnItemDataBound="DG_ItemDataBound"
. . .
>

No comments: