0
votes

I'm trying to use LINQ to sort a ObservableCollection, the problem is the LINQ's methods return a IOrderedEnumerable and there's not method to convert that type directly to ObservableCollection. After searching for a while I discovered a way do to this by using a constructor from the ObservableCollection class to create a new one using the IOrderedEnumerable:

MyObservableCollection = new ObservableCollection<T>(someIOrderedEnumerable);

However this does not solve my problem because by using this constructor the previous EventHandler is erased so I lose the references to all methods previously subscribed to the CollectionChanged event and subscribing those methods again is not possible.

Currently what I'm doing is clearing the Observable Collection and then adding the objects that were returned by the LINQ method one by one to the Observable Collection, the problem is doing this fires the CollectionChanged event many times whenever I use LINQ to order it:

var iOrderedEnumerable = MyObservableCollection.SomeLINQMethod();
MyObservableCollection.Clear();
var pivotList = iOrderedEnumerable.ToList();
for (int i = 0; i < pivotList.Count; i++)
  {
      MyObservableCollection.Add(pivotList[i]);
  }

Main question is: How do I order a Observable Collection without losing the CollectionChanged event's subscriptions?

I thought about storing the EventHandler and re-assign it after creating the new sorted Observable Collection, but haven't been able to implement this yet.

Edit1: After tinkering for a while I figured a solution for LINQ methods that only sort collections, instead of clearing the Observable Collection and then add one by one i simply set the values instead(which does not fire the CollectionChanged Event):

var iOrderedEnumerable = MyObservableCollection.SomeLINQMethod();
var pivotList = iOrderedEnumerable.ToList();
for (int i = 0; i < pivotList.Count; i++)
    {
        MyObservableCollection[i] = pivotList[i];
    }
1
"clearing the Observable Collection and then adding the objects" is the right way to go. - Enigmativity
still, it fires the event for every object added which is not desirable at all - Antnio Pedro Gonalves Ferreira
You can create your own class drives from ObservableCollection, and add IEnumerable to Items property. - weichch
@AntnioPedroGonalvesFerreira - Yes, I understand that. It's still the right way to go. - Enigmativity
@AntnioPedroGonalvesFerreira Comparing Clear&Add vs. Move in worst case => dotnetfiddle.net/nk4r2C - Sir Rufo

1 Answers

0
votes

My library ObservableComputations can help you. Using that library your code will look like following:

    ObsevableCollection<Item> orderedObsevableCollection = MyObservableCollection.Ordering(i => i.OrderKey);

ObsevableCollection will reflect all the changes in MyObservableCollection and OrderKey property of all items.