Hello, I wonder if this error (bottom of post) i'm getting is "normal". First I'll give you some background info.
I'm using CSLA 4.3.
I have a Windows UI with a Datagridview that is databound to a SortedBindingList property. Because of a business rule the list is a DynamicBindingListBase<Child>.
I'm using the SortedBindingList so that the user can also sort by clicking the column headers.
Everythings works until after I apply the sort. After considerable searching the only way I found to do a multi-propery search is using Dynamic Linq.
But the problem if I sort using Dynamic Linq I get this error. Should I be expecting this? or is there something I'm doing wrong?
This is how I implement the sort..
bindingSource.DataSource = New SortedBindingList<child>(data.AsQueryable().OrderBy("").ToList());
I know there has been numberous post regarding sorting and Dynamic Linq, and I've read them all hoping to find an answer or something that would lead me in the right direction but I found nothing that helped.
This is the error that I get.
You can use linq for all the filtering and sorting - however you must add the code to sort and wont get it automatically.
You can also use MultiColumn sorting in SortedBindingList by implementing you own PropertyDescriptor class that will return a GetValue combined of several fields.
thanks for your reply.
The sort actually works using linq, but I eventually get this error.
Could you give me a simple example of how i could implement a PropertyDescriptor class?
thanks.
I had a chat with the developer that actually did this and he chose to implement this a "virtual" MultiSortProperty that can be defined in the list and implement IComparable so that he can compare each individual property of the correct type. That is also under the assumption that it a type of "pre-defined" sortorder that the list should/could have knowledge of and maybe even specify sortorder per field.
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace MyBusiness.Logic
{
public class MultiSortProperty : IComparable
{
#region Private properties
private readonly List<IComparable> _properties;
private readonly List<ListSortDirection> _directions;
#endregion
#region Public properties
public int PropertyCount
{
get { return _properties.Count; }
}
#endregion
#region Constructors
public MultiSortProperty()
{
_properties = new List<IComparable>();
_directions = new List<ListSortDirection>();
}
public MultiSortProperty(IComparable one, IComparable two) : this()
{
AddProperty(one, ListSortDirection.Ascending);
AddProperty(two, ListSortDirection.Ascending);
}
public MultiSortProperty(IComparable one, IComparable two, ListSortDirection directionOne, ListSortDirection directionTwo) : this()
{
AddProperty(one, directionOne);
AddProperty(two, directionTwo);
}
public MultiSortProperty(IComparable one, IComparable two, IComparable three) : this()
{
AddProperty(one, ListSortDirection.Ascending);
AddProperty(two, ListSortDirection.Ascending);
AddProperty(three, ListSortDirection.Ascending);
}
public MultiSortProperty(IComparable one, IComparable two, IComparable three, IComparable four): this()
{
AddProperty(one, ListSortDirection.Ascending);
AddProperty(two, ListSortDirection.Ascending);
AddProperty(three, ListSortDirection.Ascending);
AddProperty(four, ListSortDirection.Ascending);
}
public MultiSortProperty(IComparable one, IComparable two, IComparable three, ListSortDirection directionOne, ListSortDirection directionTwo, ListSortDirection directionThree) : this()
{
AddProperty(one, directionOne);
AddProperty(two, directionTwo);
AddProperty(three, directionThree);
}
public MultiSortProperty(IComparable one, IComparable two, IComparable three,IComparable four, ListSortDirection directionOne,
ListSortDirection directionTwo, ListSortDirection directionThree , ListSortDirection directionFour) : this()
{
AddProperty(one, directionOne);
AddProperty(two, directionTwo);
AddProperty(three, directionThree);
AddProperty(four, directionFour);
}
#endregion
#region Business methods
public void AddProperty(IComparable element, ListSortDirection direction)
{
_properties.Add(element);
_directions.Add(direction);
}
public IComparable GetProperty(int index)
{
return _properties[index];
}
public IComparable GetListSortDirection(int index)
{
return _directions[index];
}
private int CompareToRecursive(MultiSortProperty that, int i)
{
// Make sure we have identical objects
if (that == null || that._properties.Count != _properties.Count) return -1;
var res = _properties.CompareTo(that._properties);
if (res == 0)
{
// They equal, check next property in list
if (_properties.Count > i + 1) return CompareToRecursive(that, i + 1);
return 0; // All elements equal
}
// They don't equal - return 1 or -1 depending on ListSortDirection
if (_directions == ListSortDirection.Descending) res = 0 - res;
return res;
}
#endregion
#region IComparable Members
public int CompareTo(object obj)
{
if (_directions.Count == 0) return 0;
var that = obj as MultiSortProperty;
if (that == null) return -1;
return CompareToRecursive(that, 0);
}
#endregion
}
}
Usage in a list:
public MultiSortProperty MyMultiSortProperty
{
get { return new MultiSortProperty(Property1, Property2, Property3); }
}
And then apply sort on the list field
<sortedBindingList>.ApplySort(MyMultiSortProperty);
this is good, thanks.
but i have a couple futher questions due to my lack of programming knowledge.
What do you mean by "usage in a list"? you mean add this property to the child class or the DynamicBindingListBase class or something else? Also, the SortBindingList I'm using doesn't accept "MyMultiSortProperty" has a parameter.
thanks.
You add the MultiSortProperty to the item in the list.
The use the MultiSortProperty.Name as input to the ApplySort method.
Hello Jonny,
I try to convert your code in VB and I have a problem with the lines :
var res = _properties.CompareTo(that._properties);
...
if (_directions == ListSortDirection.Descending) res = 0 - res;
what is the bright idea ?
Thanks in advance for help
Dominique
I found the answer : i replace the idea by (i), IE change (i) by the symbol 'idea'
and it is OK
Private Function CompareToRecursive(ByVal that As MultiSortProperty, ByVal i As Integer) As Integer
' Make sure we have identical objects
If that Is Nothing OrElse that._properties.Count <> _properties.Count Then
Return -1
End If
Dim res As Integer = _properties(i).CompareTo(that._properties(i))
If res = 0 Then
' They equal, check next property in list
If _properties.Count > i + 1 Then
Return CompareToRecursive(that, i + 1)
End If
' All elements equal
Return 0
End If
' They don't equal - return 1 or -1 depending on ListSortDirection
If _directions(i) = ListSortDirection.Descending Then
res = 0 - res
End If
Return res
End Function
Wonderful code
Thanks Jonny
Copyright (c) Marimer LLC