DataGridView automatic sorting with LINQ

DataGridView automatic sorting with LINQ

Old forum URL: forums.lhotka.net/forums/t/6833.aspx


Michael posted on Tuesday, April 21, 2009

I know there are other posts around this topic, so my apologies for bringing it up again, but I can't work out how to get a DataGridView to sort using LINQ. The ProjectTracker is now using LINQ instead of SortedBindingList, but none of the grids are sortable by clicking the column headers. Wasn't that one of the main reasons for SortedBindingList?

My code is something like:


var myBLB = MyBLB.GetMyBLB();
bindingSource.DataSource = from m in myBLB orderby m.Name select m;


Thanks
Michael

JoeFallon1 replied on Wednesday, April 22, 2009

There are two kinds of LINQ queries.
1. Those where you know the sort and filter fields at compile time.

2. This where you discover the sort and filter fields at run time.

Most people think of LINQ as #1 above. In fact your code sample does too.

But your code sample will not work at run time with clicking column names of a grid because the sort field name changes depending on which column you clicked.

The advice is to implement the Microsoft Dynamic Query Library in one of your Utility classes. Then you can pass String values as sort field name and sort direction and it will "compile" them into LINQ expressions and use them dynamically.

I have posted on this topic before - see if you can read some of the older posts for further tips.

Joe

Michael replied on Friday, April 24, 2009

Thanks for your reply, Joe.

I have downloaded and included the static class DynamicQueryable (Dynamic.cs in the Microsoft LINQ samples), and added a ToList extension method as you suggested:

public static IList ToList(this IQueryable query)
{
 
return (IList)Activator.CreateInstance(typeof(List<>).MakeGenericType(query.ElementType), query);
}


But this is as far as I've gotten (my VB skills are sorely lacking). What's the recommended way to implement DataGridView column-header-click sorting from here?

Thanks again
Michael

JoeFallon1 replied on Friday, April 24, 2009

Here is one way:

At the page level:
Private mSortedList As System.Linq.IQueryable
Private mSortDirection As ListSortDirection
Private mSortExpr As String

In a doDataBind Sub:
mSortedList = mSomeList.AsQueryable.OrderBy(mSortExpr & " " & mSortDirection.ToString)
dg.DataSource = mSortedList.ToList
DataBind()

Then in
Private Sub dg_SortCommand(ByVal source As System.Object, ByVal e As System.Web.UI.WebControls.DataGridSortCommandEventArgs) Handles dg.SortCommand
'assign the clicked sort expression to this variable so we can compare it to the previous sort value in Viewstate (or Session)

strGridSortExpression = e.SortExpression

'if user clicks same header then reverse the sort direction
If String.Compare(mSortExpr, strGridSortExpression, True) = 0 Then
If mSortDirection = ListSortDirection.Ascending Then
mSortDirection = ListSortDirection.Descending
Else
mSortDirection = ListSortDirection.Ascending
End If
Else
'user clicked a different header so start the sort as ASC
mSortDirection = ListSortDirection.Ascending
End If

mSortExpr = strGridSortExpression

doDataBind()
End Sub

You have to define a way to store the sort expr and direction values. (Session, Viewstae, some BO in Session, etc.)

HTH
Joe

Copyright (c) Marimer LLC