I have an ASP.NET GridView which has columns that look like this:
| Foo | Bar | Total1 | Total2 | Total3 |
Is it possible to create a header on two rows that looks like this?
| | Totals | | Foo | Bar | 1 | 2 | 3 |
The data in each row will remain unchanged as this is just to pretty up the header and decrease the horizontal space that the grid takes up.
The entire GridView is sortable in case that matters. I don't intend for the added "Totals" spanning column to have any sort functionality.
Edit:
Based on one of the articles given below, I created a class which inherits from GridView and adds the second header row in.
namespace CustomControls { public class TwoHeadedGridView : GridView { protected Table InnerTable { get { if (this.HasControls()) { return (Table)this.Controls[0]; } return null; } } protected override void OnDataBound(EventArgs e) { base.OnDataBound(e); this.CreateSecondHeader(); } private void CreateSecondHeader() { GridViewRow row = new GridViewRow(0, -1, DataControlRowType.Header, DataControlRowState.Normal); TableCell left = new TableHeaderCell(); left.ColumnSpan = 3; row.Cells.Add(left); TableCell totals = new TableHeaderCell(); totals.ColumnSpan = this.Columns.Count - 3; totals.Text = "Totals"; row.Cells.Add(totals); this.InnerTable.Rows.AddAt(0, row); } } }
In case you are new to ASP.NET like I am, I should also point out that you need to:
1) Register your class by adding a line like this to your web form:
<%@ Register TagPrefix="foo" NameSpace="CustomControls" Assembly="__code"%>
2) Change asp:GridView in your previous markup to foo:TwoHeadedGridView. Don't forget the closing tag.
Another edit:
You can also do this without creating a custom class.
Simply add an event handler for the DataBound event of your grid like this:
protected void gvOrganisms_DataBound(object sender, EventArgs e) { GridView grid = sender as GridView; if (grid != null) { GridViewRow row = new GridViewRow(0, -1, DataControlRowType.Header, DataControlRowState.Normal); TableCell left = new TableHeaderCell(); left.ColumnSpan = 3; row.Cells.Add(left); TableCell totals = new TableHeaderCell(); totals.ColumnSpan = grid.Columns.Count - 3; totals.Text = "Totals"; row.Cells.Add(totals); Table t = grid.Controls[0] as Table; if (t != null) { t.Rows.AddAt(0, row); } } }
The advantage of the custom control is that you can see the extra header row on the design view of your web form. The event handler method is a bit simpler, though.
I took the accepted answer approach, but added the header to the existing GridView instead of a custom inherited GridView.
After I bind my GridView, I do the following:
/*Create header row above generated header row*/ //create row GridViewRow row = new GridViewRow(0, -1, DataControlRowType.Header, DataControlRowState.Normal); //spanned cell that will span the columns I don't want to give the additional header TableCell left = new TableHeaderCell(); left.ColumnSpan = 6; row.Cells.Add(left); //spanned cell that will span the columns i want to give the additional header TableCell totals = new TableHeaderCell(); totals.ColumnSpan = myGridView.Columns.Count - 3; totals.Text = "Additional Header"; row.Cells.Add(totals); //Add the new row to the gridview as the master header row //A table is the only Control (index[0]) in a GridView ((Table)myGridView.Controls[0]).Rows.AddAt(0, row); /*fin*/
This article should point you in the right direction. You can programmatically create the row and add it to the collection at position 0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With