Persistent and Bidirectional Sorting In ASP.NET DataGrid


If you have work with sorting feature of ASP.NET DataGrid, you must have noticed that the sorting works only for the current page of the grid. As soon as you change the 'state' of the page the sorting is lost (For example when page index is changed). This is because the value of SortExpression is available only in SortCommand event. In order to persist the sorting we need to preserve this value some where. In addition to this we do not have in-built mechanism to perform bidirectional (ascending-descending) sorting. In this small article I will show you how to accomplish these tasks using ViewState object.

Requirements to run the sample code

Here, I assume that you will be using :
  • VS.NET for your development.
  • .NET Framework Beta 2
  • Employees table from Northwind database that ships with SQL Server.
We will bind data from this table to our DataGrid.

What is ViewState?

Before coding anything let us understand what a ViewState is. ViewState is a special object that ASP.NET uses to preserve state of web controls. It is this object that holds the values of various FORM elements during post backs. In reality ViewState is nothing but a hidden form field. ASP.NET exposes this 'hidden data' as a collection. You can add your custom values to this collection.

Sorting a DataGrid

In order to sort a DataGrid on some column you need to set the AllowSorting property of the DataGrid to True and then set the SortExpression property for that column. Following markup shows this :
<asp:DataGrid id="DataGrid1" runat="server"
<asp:BoundColumn DataField="lastname"
SortExpression="lastname" HeaderText="Last Name">
<asp:BoundColumn DataField="firstname"
SortExpression="firstname" HeaderText="First Name">

Note that I have omitted all the formatting markup for clarity. Once you add this code, headers of your bound columns will appear as link buttons. When you click on the link button, SortCommand event is fired.

SortCommand Event handler

The DataGrid triggers SortCommand event when user clicks on the column header for which sorting is 'on'. The SortCommand event handler has following syntax:
Private Sub DataGrid1_SortCommand
(ByVal source As Object,
ByVal e As DataGridSortCommandEventArgs)
Handles DataGrid1.SortCommand
You will get the sortexpression via e.SortExpression. This sort expression is the same that you set in DataGrid markup shown above.

In order to preserve this SortExpression we will add it to ViewState collection. We will also store sort order in the viewstate. Following code will make it clear:

viewstate.Add("sortfield", e.SortExpression)
If viewstate("sortdirection") Is Nothing Then
	viewstate.Add("sortdirection", "ASC")
	If viewstate("sortdirection") = "ASC" Then
		viewstate("sortdirection") = "DESC"
		viewstate("sortdirection") = "ASC"
	End If
End If

Here, we have added two key-value pairs to the ViewState collection. One stores the field on which the grid is to be sorted and other stores the sort direction - ascending or descending. Note that DataGrid nowhere specifies the sort direction. We need to manipulate that on our own.

Binding DataGrid with table

In our example we will bind our DataGrid to Employees table from Northwind database. We will write a Sub called BindGrid that performs actual task of binding grid. We need to call this procedure in Page Load as well as other DataGrid event handlers.
Sub BindGrid()
	Dim cnn As OleDbConnection
	Dim da As OleDbDataAdapter
	Dim ds As New DataSet()
	Dim sql As String

	If viewstate("sortfield") Is Nothing Then
		sql = "select * from employees"
		sql = "select * from employees order by " &
		viewstate("sortfield") & " " &
	End If
	cnn = New OleDbConnection
	("Provider=SQLOLEDB.1;User ID=sa;
	Initial Catalog=Northwind;
	Data Source=localhost")
	da = New OleDbDataAdapter(sql, cnn)
	da.Fill(ds, "employees")
	DataGrid1.DataSource = ds
	DataGrid1.DataMember = "employees"
End Sub

This sub simply checks the ViewState collection for the presence of sortfield and sortdirection keys and uses them in SQL queries. You can use these keys with DataView's Sort property as well.
Private Sub Page_Load
(ByVal sender As System.Object,
ByVal e As System.EventArgs)
Handles MyBase.Load

If Not Page.IsPostBack Then
End If
End Sub

Add code for PageIndexChanged event

Finally add following code in PageIndexChanged event handler :
Private Sub DataGrid1_PageIndexChanged
(ByVal source As Object,
ByVal e As DataGridPageChangedEventArgs)
Handles DataGrid1.PageIndexChanged

DataGrid1.CurrentPageIndex = e.NewPageIndex
End Sub
I hope you must have got idea of how to persist your DataGrid sorting information in ViewState.

Keep coding !

Bipin Joshi is an independent software consultant, trainer, author, and meditation teacher. He has been programming, meditating, and teaching for 25+ years. He conducts instructor-led online training courses in ASP.NET family of technologies for individuals and small groups. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Ajapa Yoga to interested individuals. To know more about him click here.

Get connected : Facebook  Twitter  LinkedIn  YouTube

Posted On : 01 December 2001

Tags : ASP.NET Server Controls Data Controls