As per page 74 of the 2008 book I am trying to replace the obsolete SortedBindingList with LINQ.
However I commonly use a SortedBindingList of ReadOnlyList (ROL) so that I can bind to a WIndows DataGridView and have sorting on column headers become automatic.
When using LINQ on a ROL it returns a IEnumerable which is not sortable and so the user can no longer use the grid headings to sort the column.
Is there a way to get LINQ to use the LINQ to CSLA tto get a LinqBindingList which I presume will give me sorting on the grid by default.
Bill
Yes. There is a way. I have been working on this for a while now.
As you noted ReadOnlyLists return IEnumerable(Of T). EditableLists return LinqBindingList(Of T).
The key is that you want to be able to pass in a String column name and Sort Direction.
In order to accomplish this you need to:
#1. Download the Microsoft Dynamic Query Library and add it to your project. This will handle String values and turn them into LINQ Expressions for you.
#2. Add this method to the MS code:
'JF - 1/5/09 added this extension:<Extension()> _
#3. Use code like this for ReadOnlyLists:
Page level variable:
Private mSortedList As System.Linq.IQueryable
In a method like doDataBind which gets called from various places like:
PageLoad, dg_SortCommand, dg_PageIndexChanged
Dim sortDir As String = ListSortDirection.Ascending '(Or Descending)
mSortedList = mROList.AsQueryable.OrderBy(strGridSortExpression &
In other methods you can refer to items in the sorted list like this:
Private Sub dg_ItemDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles dg.ItemDataBound If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then==============================================================
Alternatively you could strongly type things and use code like this:
'One issue you have to resolve though is:
'AllowCustomPaging must be true and VirtualItemCount must be set for a DataGrid with ID 'dg'
'when AllowPaging is set to true and the selected data source does not implement ICollection.
Private mSortedList As System.Linq.IQueryable(Of ROList.Info)
Dim sortDir As String = ListSortDirection.Ascending '(Or Descending)
mSortedList = mROList.AsQueryable.OrderBy(strGridSortExpression & " " & sortDir )
dg.DataSource = mSortedList ' Note: no need for .ToList anymore
Private Sub dg_ItemDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles dg.ItemDataBound
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
Dim mIndex As Integer = e.Item.DataSetIndex
Dim item As mROList.Info = mSortedList(mIndex) ' Note: no need to cast anymore.
End If
End Sub
==============================================================
I think sorting and filtering for ReadOnly lists works with the MS Dynamic Query Library.
I am working with Rocky and Aaron to get it to work for Editable Lists. Right now a normal LINQ query works for multi-column sorting as long as there is no Where clause.
Single column sorting and filtering of normal LINQ queries works for Where and OrderBy.
MS Dynamic query works for single column sorting only. No filtering yet. We are still resolving the differences in implementation of Expressions that get passed from LINQ and MS Dyn. Query.
Joe
Thanks Joe.
It would be nice if a ROL returned a LinqBindingList so that the DatGridView sort worked automatically.
Instead I have also had to wire up the grids ColumnHeaderMouseClick event to display the correct sort glyph.
Bill
Blarm:
It would be nice if a ROL returned a LinqBindingList so that the DatGridView sort worked automatically.
Bill
Bill,
I suggested the same thing to Rocky and got shot down. I just wanted it for the sake of consistency throughout my code: when you write a Linq query you get back a LinqBindingList. But now I have to keep track if it is a ROC or ECC.
BTW - how would a LinqBindingList resolve this issue for you? The column header is still a String value which varies at run time - so how can you write a real LINQ query at design time? You still need the MS Dynamic Query Library unless I am missing something. If so, please let me know.
Joe
Copyright (c) Marimer LLC