ASP.net – Sorting a gridview where datasource is bound to a list of collection of a class object

Sorting by column on a gridview when the datasource is bound to a list of collection of a class object presented quite a challenge. Since I did not use the wizard of the gridview to assign my datasource via the control and instead created and assigned the datasource programmatically, I had to progammatically get my sorting to work also.

1) The first thing I needed was set the AllowSorting property of the gridview = true.

2) In the gridview task, I then clicked on ‘Edit Columns’. Inside the Fields dialog, for my bound columns that I wanted to sort, I set the SortExpression property to the same name I used for my DataField property. After closing the dialog, the visual representation of the column names in the design view of the grid now showed them blue and underlined.

When I viewed the page in the browser, I was able to click the column header, but instead of witnessing a sort, I instead received an error that told me I had to handle the sort in my code. After trial and error and much research, I will now present the steps to implement in your server-side code behind to handle the sorting.

3) After assigning the collection to the DataSource property of the gridview, you need to save the DataSource to the ViewState:

ViewState("DataSource") = GridView1.DataSource

4) To handle the column click, you need to add the Sorting handle for the gridview along with a SortDirection function that keeps track of what column you clicked last and the direction it was last sorted in. Here are the two methods in their entirety:

Protected Sub GridView1_Sorting(sender As Object, e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles GridView1.Sorting
        Try

            '  GridView1.DataSource = Session("DataSource")
            GridView1.DataSource = ViewState("DataSource")

            Dim dt As New DataTable()
            Dim createColumns As Boolean = True
            For Each eachobj In GridView1.DataSource
                Dim t As Type = eachobj.[GetType]()
                Dim propInfos As PropertyInfo() = t.GetProperties()
                If createColumns Then
                    For Each eachProp As PropertyInfo In propInfos
                        dt.Columns.Add(eachProp.Name, GetType(Object))
                    Next
                    createColumns = False
                End If
                Dim data As Object() = New Object(propInfos.Length - 1) {}
                For i As Integer = 0 To propInfos.Length - 1
                    Dim propInfo As PropertyInfo = propInfos(i)
                    data(i) = propInfo.GetValue(eachobj, Nothing)
                Next
                dt.Rows.Add(data)
            Next


            Dim dataView1 As New Data.DataView(dt)

            dataView1.Sort = e.SortExpression & " " & GetSortDirection(e.SortExpression)

            GridView1.DataSource = dataView1
            GridView1.DataBind()

        Catch ex As Exception
            mLogger.Error(ex.Message)
        End Try
    End Sub

    Private Function GetSortDirection(ByVal column As String) As String

        ' By default, set the sort direction to ascending.
        Dim sortDirection = "ASC"

        ' Retrieve the last column that was sorted.
        Dim sortExpression = TryCast(ViewState("SortExpression"), String)

        If sortExpression IsNot Nothing Then
            ' Check if the same column is being sorted.
            ' Otherwise, the default value can be returned.
            If sortExpression = column Then
                Dim lastDirection = TryCast(ViewState("SortDirection"), String)
                If lastDirection IsNot Nothing _
                  AndAlso lastDirection = "ASC" Then

                    sortDirection = "DESC"

                End If
            End If
        End If

        ' Save new values in ViewState.
        ViewState("SortDirection") = sortDirection
        ViewState("SortExpression") = column

        Return sortDirection
    End Function

Explanation of the above methods

1) The DataSource saved previously to the ViewState is now read back in and assigned back to the gridview’s DataSource property.

2) The next chunk of logic converts the DataSource that contains my collection to a DataTable and then to a DataView.

3) The Sort property of the DataView is then assigned the SortExpression of the column and the direction of the sort determined by the GetSortDirection function.

4) The last step is to assign the DataSource property of the gridview with the DataView along with a DataBind.

You now have sorting capability.

Leave a Reply