Ever need to show something in a databound gridview that isn't in your datasource? Don't worry, relax, forget about that datasource. Just create that extra row dynamically.
Lets assume I have a GridView with 2 columns. The first column shows the items on an order, the second column shows the price of that item and the footer shows the order total. How would I inject a row that shows the tax?
Something like this in the RowDataBound EventHandler would do the trick:
decimal orderTotal = 0.0m;
decimal tax = 0.0m;
protected void gvOrderDetail_RowDataBound(object sender, GridViewRowEventArgs e)
{
//TODO: Calculate the orderTotal and the tax when RowType = DataRow
if (e.Row.RowType == DataControlRowType.Footer)
{
//Create the Row
GridViewRow row = new GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal);
//Add the two Columns
row.Cells.AddRange(CreateCells());
//get a reference to the table that holds this row
Table tbl = (e.Row.Parent as Table);
//Add the row at the end of the list, but before the footer.
tbl.Rows.AddAt(gvOrderDetail.Rows.Count + 1, row);
//Don't forget to account for any changes in the footer. Since we added a row to show the tax,
//that tax must also be accounted for in our footer. Calculating the orderTotal and the tax
//is an exercise for the reader.
Label lbl;
lbl = (Label)e.Row.FindControl("lblTotal");
lbl.Text = String.Format("{0:C}", (orderTotal + tax));
}
}
private TableCell[] CreateCells()
{
TableCell[] cells = new TableCell[2];
TableCell cell;
Label lbl;
//The order item column
cell = new TableCell();
lbl = new Label();
lbl.Text = "Sales Tax";
cell.Controls.Add(lbl);
cells[0] = cell;
//The price column
cell = new TableCell();
lbl = new Label();
lbl.Font.Bold = true;
lbl.Text = tax.ToString("C");
cell.HorizontalAlign = HorizontalAlign.Right;
cell.Controls.Add(lbl);
cells[1] = cell;
return cells;
}