ASP.NET DataGrid Column Sorting
By Doug Seven
Published: 1/18/2001
Reader Level: Intermediate
Rated: 4.67 by 3 member(s).
Tell a Friend
Rate this Article
Printable Version
Discuss in the Forums

In last two week's I have shown you how to implement both built-in and custom paging functionality using the ASP.NET DataGrid server control (See DataGrid Paging Part 1 and DataGrid Paging Part 2). This week I will show you how to implement column sorting using the DataGrid.

Downloadable source code including versions in both Visual Basic .NET and C# can be found here.

What Is Column Sorting?

Many times it is necessary to provide some sort of functionality enabling the user to resort a table of data based on a column in the table. For instance, in an online CD Store you may have a product catalog that lists CD's. The columns of data may include the artist name, CD title, the record label name and a price. For user convenience you want to allow the visitor to resort the table of products by any of the columns....for instance, a visitor who wants to view the list sorted alphabetically by CD title should be able to do so. The ASP.NET DataGrid server control has built-in functionality to handle this with only a small amount of code on your part.

Figure 1.1 - The DataGrid has built-in Column Sorting functionality

Bring It On - How to Sort

To use the DataGrid column sorting functionality you need to set a couple DataGrid properties, and provide the event handlers for the OnSortCommand event. The .NET Framework will track what column to sort by, but you need to provide the data access functionality to physically sort the data. The easiest way to do this is by dynamically building the SQL statement.

First things first. You need to create the basic framework for capturing and displaying the data. Like the two previous tutorials, I am going to work with the Customers table in the Northwind database of a SQL 7.0 server. Listing 1.1 shows the basic code to get and display the data.

Listing 1.1 - Getting and Displaying the Data

<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<html>
<head>
<title>DotNetJunkies.com - Column Sorting in the DataGrid</title>
<script runat="server" language="VB">
 Protected _sqlStmt As String = "SELECT CompanyName, ContactName, ContactTitle, Phone, Fax FROM Customers"

 Sub Page_Load(Source As Object, E As EventArgs)
  If Not Page.IsPostBack Then
   BindData()
  End If
 End Sub

 Sub BindData()
  DimconStringAsString="server=localhost;database=Northwind;uid=sa;pwd=;"
  Dim myDataSet As New DataSet
  Dim myDataAdapter As New SqlDataAdapter(_sqlStmt, conString)
  myDataAdapter.Fill(myDataSet, "Customers")
  myDataGrid.DataSource = myDataSet.Tables("Customers")
  myDataGrid.DataBind()
 End Sub
</script>
<style>
 .DataGrid {font:x-small Verdana, Arial, sans-serif}
</style>
</head>
<body>
<form runat="server" method="post">
<asp:DataGrid runat="server" id="myDataGrid"
  Border="0"
  Cellpadding="4"
  Cellspacing="0"
  AlternatingItemStyle-BackColor="#EFEFEF"
  ShowHeader="True"
  CssClass="DataGrid"
  HeaderStyle-BackColor="Black"
  HeaderStyle-ForeColor="White"
  HeaderStyle-Font-Bold="True"
/>
</form>
</body>
</html>

Break It Down

In Listing 1.1 you create a basic DataGrid to retrieve and display the Customer information from the database. Nothing to fancy here. Notice that the SQL statement (_sqlStmt) has been defined as a page-level variable. This enables access to the variable from any procedure or function on the page. You use the _sqlStmt variable in the BindData() method when creating the SqlDataAdapter. Since the _sqlStmt variable is defined as a page-level variable it is redefined and created on every page request. This will be used to your advantage when you create the OnSortCommand event handler.

To enable column sorting, much like DataGrid paging, you must set the AllowSorting property of the DataGrid to True and specify the event handler for the OnSortCommand. Listing 1.2 shows the revised DataGrid properties.

Listing 1.2 - The Revised DataGrid Properties

<asp:DataGrid runat="server" id="myDataGrid"
  Border="0"
  Cellpadding="4"
  Cellspacing="0"
  AlternatingItemStyle-BackColor="#EFEFEF"
  ShowHeader="True"
  CssClass="DataGrid"
  HeaderStyle-BackColor="Black"
  HeaderStyle-ForeColor="White"
  HeaderStyle-Font-Bold="True"
  AllowSorting="True"
  OnSortCommand="SortCommand_OnClick"
/>

In Listing 1.2 you set the AllowSorting property of the DataGrid to True. This property changes all of the column header text to hyperlinks. A click on the header text hyperlink causes a post-back and a call to the OnSortCommand event handler.

In the OnSortCommand event handler you simply need to specify how the data should be sorted, recreate the data source and bind the data to the DataGrid. Currently creating the data source and the data binding are done in the BindData() method, so really all you need to do is specify how the data should be sorted before calling the BindData() method. In other words, redefine the SQL statement. Since the SQL statement is a page-level variable you have access to it in the OnSortCommand event handler. Listing 1.3 shows the OnSortCommand event handler.

Listing 1.3 - The SortCommand_OnClick() Event Handler

Sub SortCommand_OnClick(Source As Object, E As DataGridSortCommandEventArgs)
 _sqlStmt = _sqlStmt & " ORDER BY " & E.SortExpression
 BindData()
End Sub

The name of the column is passed into the event handler as an event argument, E.SortExpression. For instance, if the user clicked on the ContactTitle column, then E.SortExpression is ContactTitle. By concatenating the SQLStmt variable with ORDER BY and the E.SortExpression value you create a SQL statement that sorts the data based on the column the user clicked on. Figure 1.2 shows the resulting page.

Figure 1.2 - Column Sorting with the DataGrid

This Is Cool, But Can I Use It With Paging?

The column sorting functionality of the DataGrid and the paging functionality can be used together. The challenge is maintaining the SortExpression information from one page to the next. As you learned in DataGrid Paging Part 1 the data source is recreated every time the used clicks a page-navigation link. To maintain the column sorting you must maintain the state of the SortExpression value. The easiest way to do this is with a hidden ASP.NET Label control. The Label control's Visible property can be set to False, hiding it from the user, but maintaining its state with ViewState. You can hold the entire SQL statement in the Label's Text property from one request to the next. There is a slight change required to the code in the previous example. Rather than using the _sqlStmt variable in the SqlDataAdapter, you need to use the Text value of the Label control. Additionally you need to set the Label's Text value when the page is first requested, and any time the OnSortCommand event handler is triggered. Listing 1.4 shows how to implement paging and sorting on the same DataGrid. See DataGrid Paging Part 1 for more information on implementing paging.

Listing 1.4 - Column Sorting and Paging Together

<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<html>
<head>
<title>ASPNextGen.com - Column Sorting in the DataGrid</title>
<script runat="server" language="VB">
 Protected _sqlStmt As String = "SELECT CompanyName, ContactName, ContactTitle, Phone, Fax FROM Customers"

 Sub Page_Load(Source As Object, E As EventArgs)
  If Not Page.IsPostBack Then
   SQLStatement.Text = _sqlStmt
   BindData()
  End If
 End Sub

 Sub BindData()
  Dim myDataSet As New DataSet
  DimConStringAsString="server=localhost;database=Northwind;uid=sa;pwd=;"
  Dim myDataAdapter As New SqlDataAdapter(SQLStatement.Text, ConString)
  myDataAdapter.Fill(myDataSet, "Customers")
  myDataGrid.DataSource = myDataSet.Tables("Customers")
  myDataGrid.DataBind()
 End Sub

 Sub PageIndexChanged_OnClick(Source As Object, E As DataGridPageChangedEventArgs)
  myDataGrid.CurrentPageIndex = E.NewPageIndex
  BindData()
 End Sub

 Sub SortCommand_OnClick(Source As Object, E As DataGridSortCommandEventArgs)
  SQLStatement.Text = _sqlStmt & " ORDER BY " & E.SortExpression
  BindData()
 End Sub
</script>
<style>
 .DataGrid {font:x-small Verdana, Arial, sans-serif}
</style>
</head>
<body>
<form runat="server" method="post">
<asp:Label id="SQLStatement" runat="server" Visible="False" />
<asp:DataGrid runat="server" id="myDataGrid"
  Border="0"
  Cellpadding="4"
  Cellspacing="0"
  AlternatingItemStyle-BackColor="#EFEFEF"
  ShowHeader="True"
  CssClass="DataGrid"
  HeaderStyle-BackColor="Black"
  HeaderStyle-ForeColor="White"
  HeaderStyle-Font-Bold="True"
  AllowSorting="True"
  OnSortCommand="SortCommand_OnClick"
  AllowPaging="True"
  OnPageIndexChanged="PageIndexChanged_OnClick"
  PageSize="10"
  PagerStyle-Mode="NumericPages"
  PagerStyle-HorizontalAlign="Right"
/>
</form>
</body>
</html>

Figure 1.3 shows the output from Listing 1.4

Figure 1.3 - Paging and Column Sorting with the DataGrid

In Listing 1.4 you implement both paging and column sorting. This is done by maintaining the SQL statement in an invisible Label control. The state of the Label control is maintained via ViewState. Regardless of how the user has chosen to sort the DataGrid, the SQL statement from the Label control is used. When the OnSortCommand event handler is triggered, the SQL statement in the Label control is updated. This allows a user to sort the DataGrid on any column, and brows from page to page maintaining the sort order.

Summary

The DataGrid server control, in my humble opinion, is one of the most powerful server controls in the ASP.NET arsenal. Through property settings and a small amount of event handler code you can generate interactive tables of data that would have taken a lot more code in classic ASP.



Marketplace
(Sponsored Links)
What are the green links?
   



 
Copyright © 2007 CMP Tech LLC |
Privacy Policy (4/10/06) | Your California Privacy Rights (4/10/06) | Terms of Service | Advertising Info | About Us | Help