R
rmgalante
Hi,
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
name.
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"
AutoGenerateColumns="False">
<Columns>
<asp:HyperLinkField "DataNavigateUrlFields="CustomerId"
DataNavigationUrlFormatString="~/YourScript.aspx?CustomerId={0}"
DataTextField="CustomerId" HeaderText="Id"
SortExpression="CustomerId"></asp:HyperLinkField>
<asp:HyperLinkField "DataNavigateUrlFields="CustomerId"
DataNavigationUrlFormatString="~/YourScript.aspx?CustomerId={0}"
DataTextField="CustomerName" HeaderText="Name"
SortExpression="CustomerName"></asp:HyperLinkField>
</Columns>
</asp:GridView>
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
follows.
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.Add(item)
Next
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
Next
If position <> i And position <> Count Then
temp = Item(i)
Item(i) = Item(position)
Item(position) = temp
End If
Next
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
String)
_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))
Else
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
Try
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) =
"asc"
oCustomers.Sort(e.SortExpression, ViewState(e.SortExpression))
GridView1.DataSource = oCustomers
GridView1.DataBind()
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.
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
name.
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"
AutoGenerateColumns="False">
<Columns>
<asp:HyperLinkField "DataNavigateUrlFields="CustomerId"
DataNavigationUrlFormatString="~/YourScript.aspx?CustomerId={0}"
DataTextField="CustomerId" HeaderText="Id"
SortExpression="CustomerId"></asp:HyperLinkField>
<asp:HyperLinkField "DataNavigateUrlFields="CustomerId"
DataNavigationUrlFormatString="~/YourScript.aspx?CustomerId={0}"
DataTextField="CustomerName" HeaderText="Name"
SortExpression="CustomerName"></asp:HyperLinkField>
</Columns>
</asp:GridView>
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
follows.
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.Add(item)
Next
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
Next
If position <> i And position <> Count Then
temp = Item(i)
Item(i) = Item(position)
Item(position) = temp
End If
Next
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
String)
_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))
Else
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
Try
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) =
"asc"
oCustomers.Sort(e.SortExpression, ViewState(e.SortExpression))
GridView1.DataSource = oCustomers
GridView1.DataBind()
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.