Sort GridView Bound to Collection of Objects




I've been experimenting with the ASP.Net GridView and encountered some
interesting issues that I thought I would share. I have a page that
loads a GridView with a generic collection of objects. For the purposes
of this discussion, the objects define a Customer, and have an id and a

I want to sort these customers by id or by name in ascending and
descending order. Here is what I did to make it work.

First I added a GridView to an ASP.Net Page.

<asp:GridView ID="GridView1" runat="server" AllowSorting="True"
<asp:HyperLinkField "DataNavigateUrlFields="CustomerId"
DataTextField="CustomerId" HeaderText="Id"
<asp:HyperLinkField "DataNavigateUrlFields="CustomerId"
DataTextField="CustomerName" HeaderText="Name"

Add your own style and formatting. Notice that I use the object's
public properties in the DataNavigateUrlFields, DataTextField and
SortExpression attributes.

Also, I did not set EnableSortingAndPagingCallbacks to true because
this caused my callbacks to stop working.

Now, I have a collection called Customers which inherits List(Of
Customer). I added an overloaded public method called Sort, which uses
a CaseInsensitiveComparer, which I will show later. The Sort methods

Public Overloads Sub Sort(ByVal strPropertyName As String, ByVal
strDirection As String)
Dim arSortedList As New ArrayList
For Each item As Customer In Me
arSortedList.Sort(New CaseInsensitiveComparer(Of
Customer)(strPropertyName, strDirection)
Dim position As Integer
Dim temp As Customer
Dim oSortedCustomer As Customer
Dim oUnsortedCustomer As Customer
For i As Integer = 0 To arSortedList.Count - 1
oSortedCustomer = CType(arSortedList(i), Customer)
For position = 0 To Count - 1
oUnsortedCustomer = CType(Item(position), Customer)
If oSortedCustomer.CustomerId = oUnsortedCustomer.CustomerId Then
Exit For
End If
If position <> i And position <> Count Then
temp = Item(i)
Item(i) = Item(position)
Item(position) = temp
End If
End Sub

Here is the generic CaseInsensitiveComparer class.

Imports System.ComponentModel
Imports System.Collections.Generic
Imports System.Reflection

Public Class CaseInsensitiveComparer(Of T)
Implements IComparer

Private _oComparer As New CaseInsensitiveComparer
Private _strDirection As String
Private _oPropInfo As PropertyInfo

Public Sub New(ByVal strPropertyName As String, ByVal strDirection As
_oPropInfo = GetType(T).GetProperty(strPropertyName)
If _oPropInfo Is Nothing Then
Throw New ArgumentException("Property not found")
End If
_strDirection = strDirection.ToLower()
End Sub

Public Function Compare(ByVal x As Object, ByVal y As Object) As
Integer Implements System.Collections.IComparer.Compare
Dim oX As T
Dim oY As T
oX = CType(x, T)
oY = CType(y, T)
If _strDirection = "asc" Then
Return _oComparer.Compare(_oPropInfo.GetValue(oX, Nothing),
_oPropInfo.GetValue(oY, Nothing))
Return _oComparer.Compare(_oPropInfo.GetValue(oY, Nothing),
_oPropInfo.GetValue(oX, Nothing))
End If
End Function

Now, my OnSorting event in the ASP page follows.

Protected Sub GridView1_Sorting(ByVal sender As Object, ByVal e As
GridViewSortEventArgs) Handles GridView1.Sorting
Dim oCustomers As Customers
oCustomers = New Customers
If oCustomers.Load() Then
If String.IsNullOrEmpty(ViewState(e.SortExpression)) Then
ViewState(e.SortExpression) = "asc"
End If
If ViewState(e.SortExpression) = "asc" Then
ViewState(e.SortExpression) = "desc" Else ViewState(e.SortExpression) =
oCustomers.Sort(e.SortExpression, ViewState(e.SortExpression))
GridView1.DataSource = oCustomers
End If
Catch ex As Exception
lblError.Text = ex.Message
End Try
End Sub

I track the sorting in view state because it has been reported that the
event argument doesn't reflect the sort direction correctly.

Comments are welcome.


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question