Now its simple to add subheader into grid or make a groupwise gridview using only two functions.

Step 1: Create Sample Table to Test
/****** Object: Table [dbo].[tblType] Script Date: 09/01/2011 23:09:11 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
IF NOT EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[tblType]') AND type in (N'U'))
BEGIN
CREATE TABLE [dbo].[tblType](
[ID] [int] IDENTITY(1,1) NOT NULL,
[TypeName] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[GrpCode] [varchar](10) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[GroupName] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NULL,
[PID] [int] NULL
)
END
GO
SET IDENTITY_INSERT [dbo].[tblType] ON
INSERT [dbo].[tblType] ([ID], [TypeName], [GrpCode], [GroupName], [PID]) VALUES (1, N'All Residential', N'-1', N'All Residential', -1)
INSERT [dbo].[tblType] ([ID], [TypeName], [GrpCode], [GroupName], [PID]) VALUES (2, N'Residential Plot', N'AR', N'All Residential', 1)
INSERT [dbo].[tblType] ([ID], [TypeName], [GrpCode], [GroupName], [PID]) VALUES (3, N'Raw House', N'AR', N'All Residential', NULL)
INSERT [dbo].[tblType] ([ID], [TypeName], [GrpCode], [GroupName], [PID]) VALUES (4, N'All Commercial', N'-2', N'All Commercial', NULL)
INSERT [dbo].[tblType] ([ID], [TypeName], [GrpCode], [GroupName], [PID]) VALUES (5, N'Office', N'AC', N'All Commercial', NULL)
INSERT [dbo].[tblType] ([ID], [TypeName], [GrpCode], [GroupName], [PID]) VALUES (6, N'Space', N'AC', N'All Commercial', NULL)
INSERT [dbo].[tblType] ([ID], [TypeName], [GrpCode], [GroupName], [PID]) VALUES (7, N'All Agricultural', NULL, N'All Agricultural', NULL)
INSERT [dbo].[tblType] ([ID], [TypeName], [GrpCode], [GroupName], [PID]) VALUES (8, N'Farm', N'AA', N'All Agricultural', NULL)
SET IDENTITY_INSERT [dbo].[tblType] OFF
Step 2: Copy and paste below code (Create function) DataTable AddRow(DataTable dt,string group)
{
if (dt != null && dt.Rows.Count > 0)
{
string cGroup="", pGroup="";
cGroup = dt.Rows[0][group].ToString().Trim();
for (int i = 0; i < dt.Rows.Count; i++)
{
if (i != 0)
{
cGroup = dt.Rows[i][group].ToString().Trim();
}
if (i > 0)
{
pGroup = dt.Rows[i - 1][group].ToString().Trim();
}
if (cGroup != pGroup)
{
DataRow dr = dt.NewRow();
//dr = dt.Rows[i].;
dr[1] = "$#$"+cGroup+"$#$";
dt.Rows.InsertAt(dr, i);
i += 1;
}
}
}
return dt;
}
Step 3: Code to fill a grid
void fillgrid()
{
string qry = "select * from tbltype";
DataTable dt= dal.fillDataTable(qry); //Do a code to get data using SqlCommand and DataAdapter
GridView1.DataSource = AddRow(dt, "GroupName"); //Call a created function,1st arg:DataTable,2nd : fieldname on which you want to group
GridView1.DataBind();
}
Step 4: Create below function to better look of grid
///
/// Use to Merge grid Cells
/// Gridview RowDataBound Event
/// Provide string to compare with cell text
/// Special text to identify for Sub header
/// Cell index which contains sub header text
/// number of columns want to span
/// Cell index of start to remove
/// Last cell index of remove cell
/// True to merge all cells
///
public static void MergeCells(GridViewRowEventArgs e, string CompareText, string symbol, int textcellindex, int colspan, int startcellindex, int lastcellindex, bool mergeallcells,string HeaderCssClass)
{
if (CompareText.Contains(symbol) == true)
{
if (mergeallcells == true)
{
e.Row.Cells[0].Attributes.Add("colspan", (e.Row.Cells.Count).ToString());
e.Row.Cells[0].Text = CompareText.Replace(symbol, ""); ;
for (int i = e.Row.Cells.Count - 1; i > 0; i--)
{
e.Row.Cells.RemoveAt(i);
}
}
else
{
e.Row.Cells[textcellindex].Text = e.Row.Cells[textcellindex].Text.Replace(symbol, "");
e.Row.Cells[textcellindex].Attributes.Add("colspan", colspan.ToString());
for (int i = lastcellindex; i >= startcellindex; i--)
{
e.Row.Cells.RemoveAt(i);
}
}
e.Row.Attributes.Add("class", HeaderCssClass);
}
}
Step 5: Create RowDataBound Event of grid
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Label lbl = e.Row.FindControl("lblTypeName") as Label;
//MergeCells(e, "$#$", 3, e.Row.Cells.Count, 3, 4, false,"tdHeader");
GridviewGroupwise.MergeCells(e,lbl.Text, "$#$", 3, e.Row.Cells.Count-1, 2, 4, true,"tdHeader");
}
}
HAPPY CODING