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

20
zachary 15 Июн 2009 в 17:29

6 ответов

Лучший ответ

Если вы используете 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

15
moonlightdock 5 Авг 2009 в 13:12

Поскольку коллекция не предоставляет никакого механизма 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();
    }
9
Icarus 26 Дек 2012 в 23:26

Обратите внимание, что в 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);
3
Brian Genisio 15 Июн 2009 в 13:33

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

Silverlight и icollectionview

3
Community 23 Май 2017 в 12:09

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

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

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

Могли бы некоторые предположить, что могло пойти не так. Благодарность

0
joblot 27 Май 2010 в 00:25

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

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

Хотя еще не использовал.

Стог

0
rboarman 4 Июн 2010 в 21:22