0

I have the following situation: I get a list of items which should be sorted by the SortId property.

I have implemented the IComparable<T> interface in my ItemViewModels, so that I can use Comparer.Default in my ICollectionView.CustomSort property to apply the sorting without using reflection (which PropertySortDescription does).

Now, my problem is that the items sometimes do not have the SortId property set because they should simply be sorted in the order they appear in the collection. However, instead of keeping the order, the items are displayed in reverse order or sometimes completely mixed - this seems to depend on the number of items.

Is there a way to avoid this behavior? If I do not apply any sorting, the items appear in the correct order. However, I would have to dynamically turn the sorting on or off, depending on the items' SortId properties - which I do not like at all... Any other ideas?

gehho
  • 9,049
  • 3
  • 45
  • 59
  • It seems to me that a combination of [this](http://stackoverflow.com/questions/2129601/how-can-i-apply-a-custom-sort-rule-to-a-wpf-datagrid) combined with a [**stable** sorting algorithm](http://en.wikipedia.org/wiki/Sorting_algorithm#Stability) would do the trick. Linq2Objects `.OrderBy` is stable. – spender Jun 23 '14 at 15:09
  • Thanks for the idea! I did not know about stable sorting algorithms so far - so at least I have learnt something new, even though I did not try this because it would change my whole sorting strategy. – gehho Jun 25 '14 at 07:45

1 Answers1

1

By updating the implementation of CompareTo method you can guarantee the sort order of those objects without SortId defined

eg

    public class MyItem : IComparable
    {
        public int? SortId { get; set; }

        public int CompareTo(object other)
        {
            if (SortId == null)
                return -1;

            MyItem otherItem = other as MyItem;
            if (otherItem == null || otherItem.SortId == null)
                return 1;

            return SortId.Value.CompareTo(otherItem.SortId.Value);
        }
    }

above will guarantee that the objects without sort id will be smaller then other

pushpraj
  • 13,458
  • 3
  • 33
  • 50
  • Thanks for your suggestion, but that is not exactly what I want. Sometimes I get _only_ items without `SortId`. In that case I do not want to sort them, but I want to keep their order as it is in the collection. However, adjusting the `CompareTo(...)` method might also work in this case. I will give it a try... – gehho Jun 24 '14 at 08:50
  • you may return 0 when SortId is not available to keep the order intact. – pushpraj Jun 24 '14 at 08:55
  • That's what I did (returning 0), but this changes the order of my items. Since they are considered equal by WPF, the order should not matter, so WPF mixes them up. Assume that the items in my _source list_ have the order 1, 2, 3, 4...9, but when returning 0 for all of them in `CompareTo`, they are _displayed_ 1, 3, 5, 7, 8, 9, 2, 4, 6! There seems to be a pattern which most probably comes from the sorting algorithm. – gehho Jun 24 '14 at 09:11
  • perhaps you should avoid sorting at all if you can determine that there is no SortId. if there are few elements in the list without then perhaps we could write an algo to determine an id for them. – pushpraj Jun 24 '14 at 09:22
  • I finally realized the desired behavior by always returning `1` if both items do not have the `SortId` property set. I do not fully understand why this works. The reason might be that the items are added one after the other and sorting is applied after every item... I do not know, but I am happy that it works! :) Thanks for the idea to modify the `CompareTo(...)` method! I did not think about that before. – gehho Jun 25 '14 at 07:34
  • I am glad it worked. in fact I learned a new approach while investigating for you. – pushpraj Jun 25 '14 at 07:36