Сортировка наблюдаемой коллекции с помощью linq - PullRequest
20 голосов
/ 15 июня 2009

У меня есть наблюдаемая коллекция, и я сортирую ее, используя linq. Все отлично, но у меня проблема в том, как отсортировать фактическую наблюдаемую коллекцию? Вместо этого я просто получаю кое-что IEnumerable, и в итоге я очищаю коллекцию и добавляю ее обратно. Это не может быть хорошим для производительности. Кто-нибудь знает лучший способ сделать это?

Ответы [ 6 ]

15 голосов
/ 05 августа 2009

Если вы используете Silverlight 3.0, то использование CollectionViewSource - самый чистый способ. Ниже приведен пример: (это также можно сделать через xaml)

ObservableCollection<DateTime> ecAll = new ObservableCollection<DateTime>();
CollectionViewSource sortedcvs = new CollectionViewSource();
sortedcvs.SortDescriptions.Add(new System.ComponentModel.SortDescription("Date", 
    System.ComponentModel.ListSortDirection.Ascending));
sortedcvs.Source = ecAll;
ListBoxContainer.DataContext = sortedcvs;

И в соответствующем наборе xaml

ItemsSource="{Binding}"

для ListBox или любого производного элемента ItemsControl

9 голосов
/ 15 июня 2009

Поскольку в коллекции нет механизма Sort, это, вероятно, наиболее практичный вариант. Вы можете реализовать сортировку вручную, используя Move и т. Д., Но, вероятно, это будет медленнее, чем при этом.

    var arr = list.OrderBy(x => x.SomeProp).ToArray();
    list.Clear();
    foreach (var item in arr) {
        list.Add(item);
    }

Кроме того, вы можете рассмотреть возможность отмены привязки любых элементов пользовательского интерфейса при сортировке (с помощью любого из подходов), которую вы платите только за повторную привязку один раз:

Интересно, что если бы это было BindingList<T>, вы могли бы использовать RaiseListChangedEvents, чтобы минимизировать количество уведомлений:

    var arr = list.OrderBy(x => x).ToArray();
    bool oldRaise = list.RaiseListChangedEvents;
    list.RaiseListChangedEvents = false;
    try {
        list.Clear();
        foreach (var item in arr) {
            list.Add(item);
        }
    } finally {
        list.RaiseListChangedEvents = oldRaise;
        if (oldRaise) list.ResetBindings();
    }
3 голосов
/ 15 июня 2009

ObservableCollections не предназначены для сортировки. Список можно сортировать, и это основной механизм, используемый ответом, ссылающимся на List.Sort (), но ObservableCollection не является производным от List, поэтому вам не повезло. По моему мнению, «правильное» решение состоит не в том, чтобы пытаться отсортировать ObservableCollection, а в том, чтобы реализовать ICollectionView и связать экземпляр этого с вашим элементом управления. Этот интерфейс добавляет методы для сортировки и имеет дополнительное преимущество, которое распознается элементами управления Silverlight (ну, в общем, теми, которые его поддерживают в любом случае, например, DataGrid), так что сортировку можно использовать непосредственно из уровня пользовательского интерфейса. Этот вопрос может быть полезен:

Silverlight и icollectionview

3 голосов
/ 15 июня 2009

Обратите внимание, что в Linq вы получаете IEnumerable из вашего запроса, и этот запрос еще не выполнен . Поэтому следующий код выполняет запрос только один раз, чтобы добавить его в коллекцию ObservableCollection:

var query = from x in Data
            where x.Tag == "Something"
            select x;

foreach(var item in query)
    MyObservableCollection.Add(item);

Взгляните на расширение " OrderBy " в IEnumerable:

foreach(var item in query.OrderBy(x => x.Name))
    MyObservableCollection.Add(item);
0 голосов
/ 05 июня 2010

Я нашел это на CodePlex:

Сортированные коллекции

Пока не использовал его.

Rick

0 голосов
/ 27 мая 2010

Я перешел по ссылке, указанной в этом сообщении http://mokosh.co.uk/post/2009/08/04/how-to-sort-observablecollection/comment-page-1/#comment-75

, но возникают проблемы с его работой в Silverlight

Я создал свойство public SortableObservableCollection Условия Когда я вызываю Terms.Sort (новый TermComparer ()), записи по-прежнему отображаются в UI

несортированными

Кто-то может подсказать, что может пойти не так. спасибо

...