

Introduction
This article describes the technique to merge the header of a DataGrid by redirecting the Render method of the DataGrid items.
Background
I found many times the need to merge the header of a DataGrid. So, when I was having spare time, I tried to find a way to do it, and here it is. I know that if you need to merge headers, you can use the Repeater control instead. But if you are fond of DataGrid (just like me), or may be you already used DataGrid, then this article is for you.
Using the code
When rendered, a DataGrid will be converted into a HTML Table element and the header will be the first HTML TR element. So, to have a merged header, we need to have control in the rendering of the header. This can be achieved by redirecting the Render method of the DataGrid header using the SetRenderMethodDelegate of the DataGrid header on ItemCreated event, like this:
private void Datagrid1_ItemCreated(object sender,
System.Web.UI.WebControls.DataGridItemEventArgs e)
{
ListItemType lit = e.Item.ItemType;
if(ListItemType.Header == lit)
{
e.Item.SetRenderMethodDelegate(new RenderMethod(NewRenderMethod));
}
}
And here is our own Render method:
private void NewRenderMethod(HtmlTextWriter writer, Control ctl)
{
writer.Write("<TD colspan=\"3\" align=\"center\">Name</TD>\n");
TableCell cell = (TableCell)ctl.Controls[ctl.Controls.Count-1];
cell.Attributes.Add("rowspan","2");
cell.RenderControl(writer);
writer.Write("</TR>\n");
DataGrid1.HeaderStyle.AddAttributesToRender(writer);
writer.RenderBeginTag("TR");
for(int i=0; i<= ctl.Controls.Count-2; i++)
{
ctl.Controls[i].RenderControl(writer);
}
}
I have created a decorator class to decorate a DataGrid (ASPNetDatagridDecorator class) to have a merge header, and all you need to do is define the header cell like this (you can use the auto format feature, but doesn't work for all):
private void Page_Load(object sender, System.EventArgs e)
{
if(!this.IsPostBack)
{
TableCell cell = null;
DataGrid1.DataSource = GetData();
DataGrid1.DataBind();
m_add.DatagridToDecorate = Datagrid2;
ArrayList header = new ArrayList();
cell = new TableCell();
cell.Text = "Name";
cell.RowSpan = 2;
cell.HorizontalAlign = HorizontalAlign.Center;
header.Add(cell);
cell = new TableCell();
cell.Text = "Name";
cell.ColumnSpan = 3;
cell.HorizontalAlign = HorizontalAlign.Center;
header.Add(cell);
cell = new TableCell();
cell.Text = "Age";
cell.RowSpan = 2;
cell.HorizontalAlign = HorizontalAlign.Center;
header.Add(cell);
cell = new TableCell();
cell.Text = "School";
cell.ColumnSpan = 3;
cell.HorizontalAlign = HorizontalAlign.Center;
header.Add(cell);
cell = new TableCell();
cell.Text = "Religion";
cell.RowSpan = 2;
cell.HorizontalAlign = HorizontalAlign.Center;
header.Add(cell);
m_add.AddMergeHeader(header);
Datagrid2.DataSource = GetData();
Datagrid2.DataBind();
}
}