Advanced DataGrid Sorting in asp.net
Submitted by nick on December 18, 2004 - 11:24.
I couldn't find any examples on what exactly I'm trying to do (as always), so I came up with one on my own. I needed to be able to sort my data grid ascending and descending, without rewriting the stored procedure, and the ability to show the sort in the DataGrid header.
- Add the AllowSorting=True tag to your DataGrid definition.
- For each bound column that you need to be able to sort by, add the SortExpression property with the sort column: SortExpression=ColumnName. It helps to just use the same value in the DataField column.
- Add a hidden variable to the page by using an asp:label server control.
- In your codebehind page, add a routine to handle the sort event. The SortExpression variable should match the value you used in the HTML page:
- Create the BindData Routine, with the optional value SortExpression. Note that I am lazy, or I would be caching the dataset to prevent the procedure from being called each time. That, and this app won't be heavily used:
- Above, we're loading the dataset, and adding in the code to determine the sort order. Basically, we're just using the label to determine if we clicked the same column we clicked before. This will tell us if we need to add the “desc“ modifier to the DataView sort Order. Then we set the sort order for the default view using your new sort and bind the DataView to the DataGrid
- The next few steps are to add the image into the Header, to show the sort order. By default, the DataGrid header either has text or an image, and can not have both.
- The first step is to interrupt the creation of the DataGrid. To accomplish this, we will add this to the DataGrid definition in the HTML page:
- In your Codebehind, add the following Routine:
- What we're doing here is 1) checking to make sure that the row we're on is the header, 2) Looping through each table cell in the header. For any cells that have one control (the LinkButton created automatically by .NET to handle the sorting), check and see if the hidden label starts with CommandArgument of the LinkButton (we use StartsWith, because the LinkButton will never know about the “desc“ modifier.
- If that does match, check the label again to see if we should be showing the up or the down arrow. Choose the right image path based on that. We are creating a new image and will programatically add it to the header.
- Add the image.
<asp:label id=lblCurrentSort Visible="False" Runat="server"/>
Sub SortEventHandler(ByVal sender As Object, _
ByVal e As DataGridSortCommandEventArgs) _
Handles dgResults.SortCommand
BindData(e.SortExpression)
End SubSub BindData(Optional ByVal SortExpression As String = "")
ds = SqlHelper.ExecuteDataset(AppSettings("conn"),_
CommandType.StoredProcedure, "sEmployeeWork")
If SortExpression <> "" Then
If lblCurrentSort.Text = SortExpression Then
'Reverse the sort
lblCurrentSort.Text = SortExpression & " desc"
Else
lblCurrentSort.Text = SortExpression
End If
Else
lblCurrentSort.Text = "LogDate" 'this is the default sort
End If
ds.Tables(0).DefaultView.Sort = lblCurrentSort.Text
dgResults.DataSource = ds.Tables(0).DefaultView
dgResults.DataBind()
End SubOnItemDataBound="AddHeader"
Protected Sub ComputeSum(ByVal sender As Object, _
ByVal e As DataGridItemEventArgs)
If e.Item.ItemType = ListItemType.Header Then
For Each tc As TableCell In e.Item.Cells
If tc.Controls.Count > 0 Then
Try
If lblCurrentSort.Text.StartsWith(CType(tc.Controls(0), _
System.Web.UI.WebControls.LinkButton).CommandArgument) Then
Dim img As New System.Web.UI.WebControls.Image
If lblCurrentSort.Text.IndexOf(" desc") >= 0 Then
img.ImageUrl = "images/sort_arrow_up.gif"
Else
img.ImageUrl = "images/sort_arrow_down.gif"
End If
tc.Controls.AddAt(0, img)
End If
Catch ex As Exception
End Try
End If
Next
End If
End SubVoila! You're done!

