Transmission
Transmission

Reputation: 1219

Sorting an ObservableCollection<BusinessObject> using a custom sort order

In WPF, I have an ObservableCollection, which I need to sort in an arbitrary custom order, meaning it's not just A-Z, the items need to be individually movable.

The BusinessObject has a field of ID, which is a string GUID. Can I have a Dictionary, storing these GUIDs and their assigned positions in the sort order, and if so, how can I apply a sort order from a separate Dictionary?

In short, I want to be able to have a manipulatable sort order for the ObservableCollection, stored in a separate object.

Upvotes: 0

Views: 721

Answers (2)

olitee
olitee

Reputation: 1683

I know you've already accepted an answer, but I've encountered a similar problem where it was important that the ObservableCollection<T> was not recreated, and that the objects in the collection were moved using the ObservableCollection.Move() method (as opposed to removed and inserted) to their new index. This was to facilitate WPF fluid move animations, etc.

In that case, I created an extension method that allowed you to pass an IEnumerable<T> of objects in the preferred sort order, and have the ObservableCollection<T> move everything into place.

It's very simple, so I post it here in case it's of any use to anyone:

public static class ObservableCollectionExtensions
{
    public static void MatchSort<T>(this ObservableCollection<T> collection, IEnumerable<T> collectionToMatchSortOrder)
    {
        int newIndex = 0;

        foreach (var item in collectionToMapSortOrder.Where(item => collection.Contains(item)))
        {
            collection.Move(collection.IndexOf(item), newIndex);
            newIndex++;
        }
    }
}

Note: This is far from foolproof, as it ideally relies on all objects present in the observable collection to be present in the IEnumerable<T>.

Upvotes: 1

James Lucas
James Lucas

Reputation: 2522

Use ICollectionView:

var view = CollectionViewSource.GetDefaultView(businessObjects);
view.SortDescriptions.Add( SortDescription("NameOfPropertyToSortBy",ListSortDirection.Ascending ));

Then expose and bind to the view value. Although, actually there is binding black magic under the covers and you don't even need to change the bound collection but it's much more maintainable if you do.

Upvotes: 1

Related Questions