Introduction
GridView
is one of the most popular controls to display data in a tabular format. But for better analysis, it requires to show the data in some summarized form like Group, Pivot, Graphs, Charts, etc. This article presents a simplified way to group your data with the appropriate aggregate functions so that you can enhance your reports with great ease. The facility to customize the group header and footer in your own way becomes the essential part when you are grouping your data. The control shown in the article has taken care of this requirement as well. If you are looking for the grouping grid in ASP.NET MVC, please have a look at Grouping Gridview in ASP.NET MVC.
Below is a screenshot of grouped data in a GridView
:
GroupGridView Control
GroupGridView
control is a custom control derived from GridView
. The primary purpose for this control is to implement the grouping feature in the GridView
. To accommodate the customized group header and footer, GroupContainer
class is created which is derived from WebControl
and INamingContainer
. This class is provided with various aggregate functions that can be applied to each group in your GridView
. The useful methods in GroupHeaderTemplate
and GroupFooterTemplate
are:
Average(ColumnName)
: Returns the average of the data present in the group for the given column Count(ColumnName)
: Returns the total number of rows present in the group for the given column First(ColumnName)
: Returns the first element of the given column in the group Last(ColumnName)
: Returns the last element of the given column in the group Max(ColumnName)
: Returns the maximum value of the data present in the group for the given column Min(ColumnName)
: Returns the minimum value of the data present in the group for the given column Sum(ColumnName)
: Returns the sum of data present in the group for the given column GetValue(DataColumn, PropertyColumn, MatchingValue)
: Returns the value of the DataColumn
whose PropertyColumn
is equal to the MatchingValue
How It Works
The logic behind grouping the data in GridView
can be divided into three parts:
- Instantiate the HeaderTemplate Template: To do this, custom control has been created with two exposed properties:
GroupHeaderTemplate
and GroupFooterTemplate
. This template needs to be instantiated for each group present in your DataSource
. This has been done by overriding the PrepareControlHierarchy()
method of GridView
. - Recognize Group and Render Group Header at proper place: To recognize the group, I have overridden
OnRowCreated()
method of the GridView
and added "group
" attribute and its value to each row of the table. To align Header
and Footer
at proper place, JQuery has been used. - Providing Hide/Show functionality to the group: The hide/show functionality to each group has been provided using JQuery. Please have a look at the
RenderClientSideGroup()
method to understand the JQuery code used to FadeIn
and FadeOut
the Group(s). You don't need to learn JQuery to use this control.
Using the Code
Using the code is simple. The control is provided with two additional Template Containers: GroupHeaderTemplate
and GroupFooterTemplate
. Both of these Template containers provide you the facility to write your own custom HTML code and use Aggregation logic to format your Header
and Footer
of the each group of GridView
.
Below is the sample aspx markup which you can write to make this control work (don't forget to include JQuery file in your code):
//Copy the GroupGridViewCtrl.dll to your bin directory. Add reference.//
<%@ Register Assembly="GroupGridViewCtrl"
Namespace="GroupGridViewCtrl" TagPrefix="gsoft" %>
...
<script type="text/javascript" language="javascript"
src="js/jquery-1.4.2.min.js"></script>
...
<gsoft:GroupGridView AllowGrouping="true" GroupColumnName="Year"
...
<GroupHeaderTemplate>
<div style="background-color:#ccddff;">
<table style="width:100%;">
<tr>
<td style="width:50%; font-weight:bold;">
<%# Container.GroupColumnName + ": " +
Container.GroupColumnData.ToString() %> </td>
<td style="width:50%;">Total Students:
<%# Container.Count("Name") %></td>
</tr>
<tr>
<td>Average Marks: <%# Math.Round((decimal)
Container.Average("Marks"), 2) %></td>
<td>Highest: <%# Container.Max("Marks") %></td>
</tr>
<tr>
<td colspan="2">Topper: <%# Container.GetValue
("Name", "Marks", Container.Max("Marks").ToString())%></td>
</tr>
</table>
</div>
</GroupHeaderTemplate>
To make this control work, don't forget to set AllowGrouping
property to true
. Moreover, GroupColumnName
property must be set to the correct value.
More Options
Based on various feedback/emails of the readers, I have included some more options in this version of GroupGridView
Control. Some of them are as follows:
- DefaultState: This control now has a property called
DefaultState
which determines whether to keep the grouped data collapsed or expanded by default. - Multiple Grids in a Page: The current version of
GroupGridView
control now allows you to have multiple GroupGridView
controls in a page working simultaneously. - EmptyGroupFooter: When the group footer is not needed, you may now simply omit the
GroupFooterTemplate
tag. - Paging: You may implement your normal paging behaviour of the
GridView
in this control, but, you need to understand that this control will group the data of the current page only. If you are implementing paging, you must watch and understand the behavior of aggregate functions used in Group Headers and Footers. - Grouping in Update Panel, etc.: In the previous version, one of the issues reported that Grouping behavior eliminates when update panel updated. In such scenarios, a JavaScript function "ApplyGrouping_ + ClientId of gridview" can be called when
UpdatePanel
got updated and it will apply the grouping behavior again. You may also use the above mentioned function to apply the grouping when grouping by default is not working due to some JavaScript error or something else. - ClientSide Options: Based on request from the readers, I have provided the option to expand/collapse the various parts of
gridview
from JavaScript. The attached sample provides you the sample code for expanding/collapsing Headers, Footers and data using JavaScript. You may explore more about it yourself.
Points of Interest
Along with grouping the data in GridView
, the sample will also provide the following things to the beginners:
- How to create a custom control
- How to create and use Template/Container Control
- How to read data from Excel Sheet
- How to use Linq to filter
DataTable
data
History
- 5th October, 2010: First version release
- 9th June, 2013: Version 1.1
- 12th June, 2013: Version 1.2: Added client side options