LarsBerg wrote:
Thanks, that put me in the right direction.
Note that I cast x and y to bytes - as ScheduleEntity.Weekday is the input to the
CMySort.Compare() - not ScheduleEntity.
For reference here is the code:
class CMySort : System.Collections.Generic.IComparer<object>
{
public int Compare(object x, object y)
{
byte a = (byte)x;
byte b = (byte)y;
if (a == 0) a = 7;
if (b == 0) b = 7;
return a.CompareTo(b);
}
}
and the call:
CMySort customSort = new CMySort();
routeLink.Schedule.Sort("Weekday", System.ComponentModel.ListSortDirection.Ascending, customSort);
This was a very unintuitive experience for me, but it works. Thanks!
BUT, I see some issues with this solution that I don't think I really can overcome.
1) This implementation doesn't sort ScheduleEntities. It sorts ScheduleEntity.Weekday. So I am limited to only sorting on 1 column. That means that I probably can't use this implementation, but have to come up with something else.
2) And I can not use IComparer in combination with EntityViews - so I have to do the sorting on the "base" collection
To be honest, I'm not sure how sorting works within LLBLGen Pro (I leave my DevExpress Grid to do sorting mainly) but I did have a quick look in CollectionCore<T>. Seems that only a single column is supported and it uses the QuickSort of List<T> to do the sorting (after putting null values first).
I see this as a problem since QuickSort is not ideal for sorting items that have multiple properties (I think the term is "non-stable sorting algorithm). If your single sort column/property descriptor has duplicate values then those rows/entities with that duplicate value will be sorted amongst themselves in random order. So if you have a grid and change the sort direction then change it back again, the rows displayed will not necessarily be in the same order you started with.
Ideally, you want to be able to take control of the whole sorting process by being able to use your custom comparer on the whole object rather than just the single sort field.
That way you can write custom comparers with any level of comparison.
Maybe the support team can advise of a way of using a custom IComparer in a View.
Here is some sample code (similar to what you had originally) for a ScheduleSorter to show how to sort by multiple fields. Taking this further, it should be possible to write a generic Comparer for multiple fields along the same principle, ie keep going through the list of sort fields until a non-zero result is found. (I think I have one somewhere that used reflection to sort by any number of properties - not fast but could be speeded up using .NET20 features and/or LLBLGen metadata)
public int Compare(object x, object y)
{
int result = 0;
ScheduleEntity left = (ScheduleEntity) x;
ScheduleEntity right = (ScheduleEntity) y;
// Sort by adjusted weekday first
int a = Convert.ToInt32(x.Weekday);
int b = Convert.ToInt32(y.Weekday);
if (a == 0) a = 7;
if (b == 0) b = 7;
result = a.CompareTo(b);
if (result != 0)
{
if (_weekDaySortOrder == SortOrder.Descending) result = -result;
}
else
{
// Both the same, so do another comparison here
result = left.OtherField.CompareTo(right.OtherField);
if (result != 0)
{
if (_otherFieldSortOrder == SortOrder.Descending) result = -result;
}
else {
// Repeat further comparisons here
}
}
return result;
}
Cheers
Simon