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.