MergingGrid.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MergingGrid.aspx.cs" Inherits="GridSample.MergingGrid" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Untitled Page</title>
<style type="text/css">
.header
{
background-color: blue;
color:white;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:gridview ID="grid" runat="server" AutoGenerateColumns="false" OnRowCreated="GridView1_RowCreated" HeaderStyle-CssClass="header" onsorting="GridView1_Sorting" AllowSorting="true">
<Columns>
<asp:BoundField DataField="Name" HeaderText="Name" SortExpression="Name"/>
<asp:BoundField DataField="Mathematics" HeaderText="Mathematics" SortExpression="Mathematics" />
<asp:BoundField DataField="Georgaphy" HeaderText="Georgaphy" SortExpression="Georgaphy" />
<asp:BoundField DataField="Biology" HeaderText="Biology" SortExpression="Biology"/>
<asp:BoundField DataField="Average" HeaderText="Average" SortExpression="Average"/>
</Columns>
</asp:gridview>
</div>
</form>
</body>
</html>
MergingGrid.aspx.cs :
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Collections.Generic;
namespace GridSample
{
public partial class MergingGrid : System.Web.UI.Page
{
#region Private
[Serializable]
private class MergedColumnsInfo
{
// indexes of merged columns
public List<int> MergedColumns = new List<int>();
// key-value pairs: key = first column index, value = number of merged columns
public Hashtable StartColumns = new Hashtable();
// key-value pairs: key = first column index, value = common title of merged columns
public Hashtable Titles = new Hashtable();
//parameters: merged columns's indexes, common title of merged columns
public void AddMergedColumns(int[] columnsIndexes, string title)
{
MergedColumns.AddRange(columnsIndexes);
StartColumns.Add(columnsIndexes[0], columnsIndexes.Length);
Titles.Add(columnsIndexes[0], title);
}
}
//property for storing of information about merged columns
private MergedColumnsInfo info
{
get
{
if (ViewState["info"] == null)
ViewState["info"] = new MergedColumnsInfo();
return (MergedColumnsInfo)ViewState["info"]; }
}
//method for rendering of columns's headers
private void RenderHeader(HtmlTextWriter output, Control container)
{
for (int i = 0; i < container.Controls.Count; i++)
{
TableCell cell = (TableCell)container.Controls[i];
//stretch non merged columns for two rows
if (!info.MergedColumns.Contains(i))
{
cell.Attributes["rowspan"] = "2";
cell.RenderControl(output);
}
else //render merged columns's common title
if (info.StartColumns.Contains(i))
{
output.Write(string.Format("
",
info.StartColumns[i], info.Titles[i]));
}
}
//close first row
output.RenderEndTag();
//set attributes for second row
grid.HeaderStyle.AddAttributesToRender(output);
//start second row
output.RenderBeginTag("tr");
//render second row (only merged columns)
for (int i = 0; i < info.MergedColumns.Count; i++)
{
TableCell cell = (TableCell)container.Controls[info.MergedColumns[i]];
cell.RenderControl(output);
}
}
private DataTable GetDataSource()
{
DataTable table = new DataTable();
table.Columns.Add("Name");
table.Columns.Add("Mathematics", typeof(int));
table.Columns.Add("Georgaphy");
table.Columns.Add("Biology");
table.Columns.Add("Average");
table.Rows.Add(new object[] { "A. Ivanova", 3, 5, 4, 4 });
table.Rows.Add(new object[] { "I. Petrenko", 5, 5, 4, 4.67 });
table.Rows.Add(new object[] { "O. Kovaleva", 5, 3, 5, 4.33 });
table.Rows.Add(new object[] { "R. Bubka", 5, 5, 5, 5 });
return table;
}
#endregion
#region Event Handlers
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
//merge second, third and fourth columns with common title "Subjects"
info.AddMergedColumns(new int[] { 1, 2, 3 }, "Subjects");
grid.DataSource = GetDataSource();
grid.DataBind();
}
}
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
//call the method for custom rendering of columns's headers
if (e.Row.RowType == DataControlRowType.Header)
e.Row.SetRenderMethodDelegate(RenderHeader);
}
public SortDirection dir
{
get
{
if (ViewState["dirState"] == null)
{
ViewState["dirState"] = SortDirection.Ascending;
}
return (SortDirection)ViewState["dirState"];
}
set
{
ViewState["dirState"] = value;
}
}
protected void GridView1_Sorting(object sender, GridViewSortEventArgs e)
{
string sortingDirection = string.Empty;
if (dir == SortDirection.Ascending)
{
dir = SortDirection.Descending;
sortingDirection = "Desc";
}
else
{
dir = SortDirection.Ascending;
sortingDirection = "Asc";
}
DataView sortedView = new DataView(GetDataSource());
sortedView.Sort = e.SortExpression + " " + sortingDirection;
grid.DataSource = sortedView;
grid.DataBind();
}
#endregion
}
}