In this article I will be showing you how to spruce up the gridview and group your columns for a better user experience.
We will be changing the GridView from this:

To this:

To accomplish this is very simple and I will only be showing a simplified version here, but this should give you some good ideas of where to go from here. First you will need to create a new C# web project in Visual Studio.
Replace the contents of default.aspx with this:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//Dth XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/Dth/xhtml1-transitional.dth">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Untitled Page</title>
<style type="text/css">
.header
{
background:blue;
color:White;
font-weight:bold;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="gvSample" runat="server" AutoGenerateColumns="False"
onrowcreated="gvSample_RowCreated" Width="100%">
<Columns>
<asp:BoundField DataField="Name" HeaderText="Name" />
<asp:BoundField HeaderText="Sales" DataField="Q1_Sales_Amount" />
<asp:BoundField HeaderText="Dollars" DataField="Q1_Sales_Dollars" DataFormatString="{0:C}" />
<asp:BoundField HeaderText="Amount" DataField="Q2_Sales_Amount" />
<asp:BoundField HeaderText="Dollars" DataField="Q2_Sales_Dollars" DataFormatString="{0:C}" />
<asp:BoundField HeaderText="Amount" DataField="Q3_Sales_Amount" />
<asp:BoundField HeaderText="Dollars" DataField="Q3_Sales_Dollars" DataFormatString="{0:C}" />
<asp:BoundField HeaderText="Amount" DataField="Q4_Sales_Amount" />
<asp:BoundField HeaderText="Dollars" DataField="Q4_Sales_Dollars" DataFormatString="{0:C}" />
</Columns>
<HeaderStyle CssClass="header" />
</asp:GridView>
</div>
</form>
</body>
</html>
This will set up our page with a GridView and the columns that we will be using.
Next we will add the code that will create our column grouping.
In the CodeBehind add a reference at the top to System.Text:
using System.Text;
Now add the following method:
private DataTable GetData()
{
DataTable dtReturn = new DataTable();
//Create the columns
dtReturn.Columns.Add(new DataColumn("Name", typeof(string)));
dtReturn.Columns.Add(new DataColumn("Q1_Sales_Amount", typeof(int)));
dtReturn.Columns.Add(new DataColumn("Q1_Sales_Dollars", typeof(double)));
dtReturn.Columns.Add(new DataColumn("Q2_Sales_Amount", typeof(int)));
dtReturn.Columns.Add(new DataColumn("Q2_Sales_Dollars", typeof(double)));
dtReturn.Columns.Add(new DataColumn("Q3_Sales_Amount", typeof(int)));
dtReturn.Columns.Add(new DataColumn("Q3_Sales_Dollars", typeof(double)));
dtReturn.Columns.Add(new DataColumn("Q4_Sales_Amount", typeof(int)));
dtReturn.Columns.Add(new DataColumn("Q4_Sales_Dollars", typeof(double)));
//Populate the table
Random rndGen = new Random();
for (int i = 0; i < 20; i++)
{
DataRow drNew = dtReturn.NewRow();
drNew["Name"] = "Foo" + i.ToString();
drNew["Q1_Sales_Amount"] = rndGen.Next(100,1000);
drNew["Q1_Sales_Dollars"] = rndGen.Next(1000, 10000);
drNew["Q2_Sales_Amount"] = rndGen.Next(100, 1000);
drNew["Q2_Sales_Dollars"] = rndGen.Next(1000, 10000);
drNew["Q3_Sales_Amount"] = rndGen.Next(100, 1000);
drNew["Q3_Sales_Dollars"] = rndGen.Next(1000, 10000);
drNew["Q4_Sales_Amount"] = rndGen.Next(100, 1000);
drNew["Q4_Sales_Dollars"] = rndGen.Next(1000, 10000);
dtReturn.Rows.Add(drNew);
}
return dtReturn;
}
This method will create some sample data for our tutorial. Next we will add two lines to the Page_Load event. These just set the data source and binds the data to the GridView.
protected void Page_Load(object sender, EventArgs e)
{
this.gvSample.DataSource = this.GetData();
this.gvSample.DataBind();
}
Now we will add the event that will create the column grouping. Add this to your code file:
protected void gvSample_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.Header)
{
//Now we are going to group columns 1-2, 3-4, 5-6
//We accomplish this by injecting HTML into the first cell of the header row
StringBuilder sbNewHeader = new StringBuilder();
sbNewHeader.AppendFormat(" </th><th colspan='2' align='center'>Q1</th><th colspan='2' align='center'>Q2</th><th colspan='2' align='center'>Q3</th><th colspan='2' align='center'>Q4</th></tr>");
sbNewHeader.AppendFormat("<tr class='{0}'><th>{1}", this.gvSample.HeaderStyle.CssClass, e.Row.Cells[0].Text);
e.Row.Cells[0].Text = sbNewHeader.ToString();
}
}
This event is already bound in the GridView when you pasted it into your page earlier. What this does is first test to see if the row is a header row. If the row is a header it then creates a StringBuilder object. The string builder is used to create an HTML fragment that will be injected into the text of the first header row cell. This will create a new row populated with cells that use column spanning to groups the columns below it. The row is then ended and a new row and cell started. And there you have it, a GridView that has column grouping. Hopefully someone will find this of use, if you have any questions please fell free to ask them.