Сортировка списка против ObservableCollection - PullRequest
4 голосов
/ 25 февраля 2010

Я обнаружил, что я "делаю WPF неправильно" и, к сожалению, должен пересмотреть большую часть своего кода.

Как я могу преобразовать следующее:

public static class SortName 
    {
       public static  int Compare(Person a, Person b)
        {
            return a.Name.CompareTo(b.Name);
        }

    }

и я называю это как:

list.Sort(SortName.Compare);

в формате, необходимом для ObservableCollection. И как бы я это назвал. Пока я пробовал это на основе того, что я прочитал здесь

class ObservableCollectionSortName<T> : ObservableCollection<T> 
{
    public int Compare (Person a, Person b)
    {
        return a.Name.CompareTo(b.Name);
    }
}

Ответы [ 2 ]

14 голосов
/ 25 февраля 2010

Наблюдаемая коллекция не осуществляет сортировку, по той простой причине, что каждый раз, когда элемент перемещается из одного места в списке в другое, коллекция вызывает событие. Это было бы замечательно для просмотра анимации алгоритма сортировки в действии, но это было бы отстойно, вы знаете, для сортировки.

Есть два способа сделать это; они очень похожи, и оба начинают с сортировки предметов за пределами своей наблюдаемой коллекции, например если _Fruits является ObservableCollection<Fruit>, и вы определили IComparer<Fruit> для сортировки, вы должны сделать:

var sorted = _Fruits.OrderBy(x => x, new FruitComparer());

Это создает новый IEnumerable<Fruit>, который при переборе по нему будет иметь объекты в новом порядке. Есть две вещи, которые вы можете сделать с этим.

Один из них - создать новую коллекцию, заменить старую и заставить все элементы управления в пользовательском интерфейсе повторно выполнить привязку к ней:

_Fruits = new ObservableCollection<Fruit>(sorted);
OnPropertyChanged("Fruits");

(Предполагается, что ваш класс реализует INotifyPropertyChanged обычным способом.)

Другой способ - создать новый отсортированный список, а затем использовать его для перемещения элементов в вашей коллекции:

int i = 0;
foreach (Fruit f in sorted)
{
   _Fruits.MoveItem(_Fruits.IndexOf(f), i);
   i++;
}

Второй подход - это то, что я бы попробовал, только если бы у меня было действительно серьезное обязательство не связывать элементы управления элементами, потому что это вызовет массу событий, измененных коллекцией.

3 голосов
/ 25 февраля 2010

Если основная причина сортировки вашей наблюдаемой коллекции состоит в том, чтобы отображать данные в отсортированном списке пользователю, а не по соображениям производительности (то есть более быстрого доступа), тогда можно использовать CollectionViewSource. У Bea Stollnitz есть хорошее описание в ее блоге , как использовать CollectionViewSource для реализации сортировки и группировки коллекций для пользовательского интерфейса .

Это может помочь, так как это означает, что вам не придется реализовывать сортировку в вашей наблюдаемой коллекции и беспокоиться о сбоях производительности, указанных Робертом при отправке INotifyCollectionChanged. Однако это позволит отображать элементы в отсортированном порядке в пользовательском интерфейсе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...