Added extensions to sorting a list and improved sort.

Added extensions to sorting a list and improved sort.

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


Brian Criswell posted on Sunday, September 17, 2006

I have updated the ObjectListView on the CSLAcontrib site with the following improvements:
The next improvement I am looking to do will be to change the way sorts are applied to be more like the DataView.  So you will be able to do the following code:
ObjectListView view = new ObjectListView(myList, "Name, CreatedDate DESC");

I will most likely move IBindingListView.SortDescriptions to a private implementation and remove the redundant constructors on ObjectListView at that time, which will be a breaking change.

Please post any bug reports or suggestions here (thanks to Xal for the suggestion about the ExtendSort event).

Update: I have added a .Sort property that works like the DataView.Sort property.  This has allowed the constructors to be consolidated down to 3 overloads, which is a breaking change (compile time) as only ObjectListView(IList list) carries over.  I have also moved many of the IBindingListView and IBindingList methods into private implementations to simplify the exposed methods.

JoeFallon1 replied on Monday, September 18, 2006

These are all nice improvements - especially the sorting time reduction.

Thanks!

I will download the latest version and do a little testing.

Seems to work fine. Thanks.

Can you add a constructor so we can skip passing String.Empty for the filter when we use this one:

public ObjectListView(IList list, string propertyName, ListSortDirection direction, string filter)

: this(list, new ObjectView.ObjectViewPropertyDescriptor(TypeDescriptor.GetProperties(list.GetType().GetProperty("Item", new Type[] { typeof(int) }).PropertyType)[propertyName]), direction, filter)

{

}

 

e.g. can you add:

public ObjectListView(IList list, string propertyName, ListSortDirection direction)

: this(list, new ObjectView.ObjectViewPropertyDescriptor(TypeDescriptor.GetProperties(list.GetType().GetProperty("Item", new Type[] { typeof(int) }).PropertyType)[propertyName]), direction, string.Empty)

{

}

 

Joe

 

Brian Criswell replied on Monday, September 18, 2006

Hi Joe,

I will address this when moving to a DataView style for the Sort property.  So the constructors will look like:
So in your example you would delete the list sort direction (and optionally put "DESC" into the sort).  I may also include an overload for setting up the default item with values.

JoeFallon1 replied on Tuesday, September 19, 2006

Brian,

Can you address the problem with this warning: "Return type of function GetDataSource is not CLS-compliant". I get it when I build a function like the one shown below. I am not sure what it means - but I don;t want to add attributes all over the place if I don't have to.

Protected Function GetDataSource(ByVal key As Integer) As ObjectListView

    Dim filteredList As ObjectListView

    'code here

    Return filteredList

End Function

Brian Criswell replied on Tuesday, September 19, 2006

Hi Joe,

I do not have that problem.  So my guess is that you are using an older version of CSLA 2 that did not have the ClsCompliant attribute set.  Add the following to AssemblyInfo.cs:

// Mark the assembly as CLS compliant
[assembly: System.CLSCompliant(true)]

Brian Criswell replied on Wednesday, September 20, 2006

I found an initialization bug this morning and uploaded a fixed version to CodePlex around 10:00 BST.

JoeFallon1 replied on Wednesday, September 20, 2006

Hi Brian,

A coupe of things.

1. The shorter list of constructors is a little too short. A lot of my code uses the ListSortDirection enumeration and I would like to be able to continue to use it rather than build a "DESC" string.

In my web page I have code like this:

     Dim props() As String = {"code", "descr"}
     Dim directions() As ListSortDirection = {ListSortDirection.Ascending, ListSortDirection.Descending}
    sortedList = GetObjectListView(mList, props, directions)

The function GetObjectListView is in a Utility class:

Public Shared Function GetObjectListView(ByVal list As IList, ByVal props() As String, ByVal directions() As ListSortDirection) As ObjectListView

If list IsNot Nothing AndAlso list.Count > 0 Then

  Dim properties As PropertyDescriptorCollection = TypeDescriptor.GetProperties(list.Item(0))

  Dim numProps As Integer = props.GetUpperBound(0)

  Dim sortDescs(numProps) As ListSortDescription

  For i As Integer = 0 To numProps

    sortDescs(i) = New ListSortDescription(properties.Find(props(i), False), directions(i))

  Next

  Dim sortsColl As New ListSortDescriptionCollection(sortDescs)

  Dim result As New ObjectListView(list, sortsColl)

  Return result

Else

  Return Nothing

End If

End Function

 

As you can see, the final call in that function is to the constructor:

public ObjectListView(IList list, ListSortDescriptionCollection sorts, string filter)

So that is another one that I would like to see kept around.

=======================================================

As to the CLS-Compliant problem - I have compiled your source code separately from CSLA2 because I am using the VB version of CSLA. I found the AssemblyInfo file in the project I use with your source code and added the attribute [assembly: System.CLSCompliant(true)].

Then I re-compiled and the problem went away. Thanks for the tip.

Joe

 

Brian Criswell replied on Wednesday, September 20, 2006

Hi Joe,

I wanted to keep the list of constructors as small and simple as possible.  However, there is no reason why you cannot modify the code yourself or change the following line in your method from:

Dim result As New ObjectListView(list, sortsColl)

to

Dim result As New ObjectListView(list)
DirectCast(result, IBindingListView).ApplySort(sortsColl)

Alternatively, you could make a helper method that converts the the sortColl to the string for you.  I do not really want to add the constructor back in as I had to replace it with the new version, and putting the old one back in would add another code path to maintain.  In both the old version and the new version, all constructors pass their arguments to a single constructor that does all the work.  I would have to change that to accommodate the old way of applying the sort.

Because you are using a method to generate your ObjectListView, you can absorb the impact of this change very easily.

Public Shared Function GetObjectListView(ByVal list As IList, ByVal props() As String, ByVal directions() As ListSortDirection) As ObjectListView
    If
list IsNot Nothing AndAlso list.Count > 0 Then
        Dim sort As New System.Text.StringBuilder();

        For i As Integer = 0 To props.Count - 1
            If sb.Length > 0 Then
                sb.Append(", ")
            End If

            sb.Append(props(i))

            If directions(i) = ListSortDirection.Descending Then
                sb.Append(" DESC")

            End If

        Next

        Return New ObjectListView(list, sort.ToString())
    End
If

    Return Nothing
End
Function



JoOfMetL replied on Wednesday, September 20, 2006


Hi,

It is surely a stupid question, but the framework of Mr. Lhotka does not contain it not already objects SortedBindingLIst and FilteredBindingList.

It is not the same thing?

Brian Criswell replied on Wednesday, September 20, 2006

No, they are different from the ObjectListView.  I started work on the ObjectListView to do a couple of things that SortedBindingList did not do.

JoOfMetL replied on Wednesday, September 20, 2006


Thank you for its precise details

JoeFallon1 replied on Thursday, September 21, 2006

Brian,

OK - I got the latest version and "took the hint" about modifying the function. I tweaked it a bit to get it to compile. <g> Then I overloaded it so a could do the same thing for a single property. That way my calling code always calls the function but if I have multiple properties then I have to add 2 lines of code to buld the 2 arrays for props and directions. Testing shows it works just fine.

I also like your list of reasons as to why this control offers more use and flexibility than the 2 that come with CSLA. My main purpose in using this was to get multi-property sorting. The filtering and performance are bonuses.

Thanks for building such a nice contrl and sharing it with the CSLA community. Once it gets more exposure and is "fully debugged" and "has all the features"  it would be nice if Rocky could incorporate it directly into CSLA.

Very nice work.

Copyright (c) Marimer LLC