We will use the Employees table from Northwind Database. The
grouping will be based on field Title of Employees table.
For the sample let us associate GridView control to the
SqlDataSource control (this can be done using any appropriate DataSource control).
The SqlDataSource control is shown in Listing 1.
As the grouping is done using the Title column, we will have
SQL query with Order by title.
Listing 1 – Use SqlDataSource to populate GridView
control
<asp:SqlDataSource ID="SqlDatasource1" runat="server"
SelectCommand="Select lastname,title from Employees order by title"
ConnectionString="Server=localhost;uid=sa;password=;database=Northwind">
</asp:SqlDataSource>
The GridView control will have TemplateField with two label
controls, one for field LastName and the other for Title as shown in Listing 2.
Listing 2 – GridView control
<asp:GridView
AutoGenerateColumns="false" ID="GridView1"
runat="server" DataSourceID="SqlDataSource1"
OnRowDataBound="GVRowDB" >
<Columns>
<asp:TemplateField HeaderText="Employee Data">
<ItemTemplate>
<asp:Label ID="lblTitle" runat="server" Text='<%#Eval("title")%>'></asp:Label>
<asp:Label ID="lblName" runat="server"
Text='<%#Eval("Lastname")%>'></asp:Label> </ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Our goal is to group the data based on the field Title. As
GridView control does not have an ItemDataBound event, let us play with the
RowDataBound event and see if it is possible to achieve what we are looking for
(In listing 2 we have already made a room to write code for the event).
GridView's RowType property determines the type of rows represented
by GridViewRow object. This can be the Header, Footer, Pager, Seperator or the
DataRow.
We want the grouping according to the Title column, which is
displayed in the label control of the ItemTemplate in GridView. The RowType we
will check for is DataRow.
As the label in the GridView control has the column data for
Title, FindControl will give us the text and other properties associated with label
control.
Initially, we will check the value of the label control and
store it in temporary variable. Based on the value of the label control, we
will set the visibility of the label control to true or false. Listing 3 shows
the code for this.
Listing 3 – (Method 1) Grouping data in GridView
Control using RowDataBound
[Visual Basic 2005]
Protected Sub GVRowDB(ByVal sender As Object, _
ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow Then
Dim titleLabel As Label = e.Row.FindControl("lblTitle")
Dim strval As String = CType(titleLabel, Label).Text
Dim title As String = ViewState("title")
If title = strval Then
titleLabel.Visible = False
titleLabel.Text = String.Empty
Else
title = strval
ViewState("title") = title
titleLabel.Visible = True
titleLabel.Text = "<br><b>" & title & "</b><br>"
End If
End sub
[C#]
protected void GVRowDB(object sender, System.Web.UI.WebControls.GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Label titleLabel = (Label)e.Row.FindControl("lblTitle");
string strval = ((Label)(titleLabel)).Text;
string title = (string)ViewState["title"];
if (title == strval)
{
titleLabel.Visible = false;
titleLabel.Text = string.Empty;
}
else
{
title = strval;
ViewState["title"] = title;
titleLabel.Visible = true;
titleLabel.Text = "<br><b>" + title + "</b><br>";
}
}
}
In Method 2 we will use Helper function as shown in Listing
4.
Listing 4 – (Method 2) Grouping data in GridView
Control using Helper function
<asp:GridView AutoGenerateColumns="false" ID="GridView1"
runat="server" DataSourceID="SqlDataSource1">
<Columns>
<asp:TemplateField HeaderText="Employee Data">
<ItemTemplate>
<asp:Label ID="lblTitle"
runat="server" Text='<%#CheckIfTitleExists(Eval("title").ToString())%>'></asp:Label>
<asp:Label ID="lblName" runat="server"
Text='<%#Eval("Lastname")%>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDatasource1" runat="server"
SelectCommand="Select lastname,title from Employees order by title"
ConnectionString="Server=localhost;uid=sa;password=;database=Northwind">
</asp:SqlDataSource>
[Visual Basic 2005]
Protected Function CheckIfTitleExists(ByVal strval As String) As String
Dim title As String = ViewState("title")
If title = strval Then
return String.Empty
Else
title = strval
ViewState("title") = title
return "<br><b>" & title & "</b><br>"
End If
End Function
[C#]
protected string CheckIfTitleExists(string strval)
{
string title = (string)ViewState["title"];
if (title == strval)
{
return string.Empty;
}
else
{
title = strval;
ViewState["title"] = title;
return "<br><b>" + title + "</b><br>";
}
}