2

In my program I have TreeView nodes that I need to be able to shift up and down, basically change the order. My TreeView is an ObservableCollection of a specific Data Model. Each node has a property called "Rank", this is the value that I would like to sort the collection by. With that being said I referred to this question. From that question I discovered this blog page. I am attempting the second method involving the sort function of a List.

This is the example that I am looking at:

List<Person> list = new List<Person>(people);
list.Sort();

Please note that the "Rank" value of each node is in working order and changing correctly. I just need to find a way to re-order the collection based off of that property and reflect it in the View.

My Problem: When trying to implement the above solution I get an InvalidOperationException. I feel like I do not understand how to tell the List to sort based off of rank.

What my code looks like:

List<TreeModel> sortedTree = new List<TreeModel>(TreeCollection);
sortedTree.Sort();

What am I missing here? How do I sort the collection based off of the rank property and reflect those changes in the view?

Thank you.

*I believe I may have posted about this before, so if for some reason this question is too similar my older one, I'll just delete the old one.

Community
  • 1
  • 1
Eric after dark
  • 1,768
  • 4
  • 31
  • 79

2 Answers2

1

Sort throws InvalidOperationException its component type does not have a default comparison:

The default comparer Comparer.Default cannot find an implementation of the IComparable generic interface or the IComparable interface for type T.

You can however supply the comparison as the first parameter to Sort:

sortedTree.Sort((x, y) => x.Rank.CompareTo(y.Rank));

To pass the sorted items back to the original collection, you could either clear/repopulate CurrentCollection, or simply assign it a new instance (don't forget to RaisePropertyChanged if you do the latter):

CurrentCollection = new ObservableCollection<TreeModel>(sortedTree);
McGarnagle
  • 101,349
  • 31
  • 229
  • 260
  • Okay, so this makes it so that the `List` will sort based off of the integer stored in Rank. After doing that won't I need to set the current `ObservableCollection` equal to the new sorted one? – Eric after dark Dec 05 '13 at 20:54
  • @Ericafterdark yes exactly, you'd need to either create a new `ObservableCollection`, or clear/re-populate the existing one (the former is probably easier). – McGarnagle Dec 05 '13 at 21:04
  • this is what I just did: `CurrentCollection = new ObservableCollection(sortedTree);`. It doesn't seem to affect the view though. Maybe I am forgetting PropertyChanged? – Eric after dark Dec 05 '13 at 21:07
  • 1
    @Ericafterdark right, if you replace the collection, you'd need to raise PropertyChanged ... – McGarnagle Dec 05 '13 at 21:11
  • Worked like a charm! You might want to add the code that I used in that comment there to your answer. Thank you! – Eric after dark Dec 05 '13 at 21:18
1

You need to pass property name on which you want to sort your list like this -

sortedTree = sortedTree.OrderBy(m => m.Rank).ToList();
Rohit Vats
  • 79,502
  • 12
  • 161
  • 185