排序列表与ObservableCollection

时间:2010-02-25 00:18:37

标签: c# wpf visual-studio-2008

我发现我“正在做WPF错误”并且令人沮丧地必须彻底检查我的代码。

我如何转换以下内容:

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

    }

我称之为:

list.Sort(SortName.Compare);

到ObservableCollection所需的格式。我怎么称呼它。到目前为止,我已根据我阅读here

的内容尝试了以下内容
class ObservableCollectionSortName<T> : ObservableCollection<T> 
{
    public int Compare (Person a, Person b)
    {
        return a.Name.CompareTo(b.Name);
    }
}

2 个答案:

答案 0 :(得分:14)

可观察集合不实现排序,原因很简单,每当项目从列表中的一个位置移动到另一个位置时,集合就会引发一个事件。这对于观看排序算法的动画非常有用,但是对于排序来说,它会很糟糕。

有两种方法可以做到这一点;它们非常相似,都是通过对可观察集合之外的项目进行排序开始的,例如如果_FruitsObservableCollection<Fruit>,并且您为排序定义了IComparer<Fruit>,则可以执行以下操作:

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

这会创建一个新的IEnumerable<Fruit>,当你迭代它时,它将拥有新顺序的对象。你可以用两件事做这件事。

一个是创建一个新集合,替换旧集合,并强制UI中的任何项目控件重新绑定到它:

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

(这假定您的类以通常的方式实现INotifyPropertyChanged。)

另一种方法是创建一个新的排序列表,然后用它来移动集合中的项目:

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

第二种方法是我只会尝试,如果我非常认真地承诺不重新绑定项目控件,因为它会引发大量的收集更改事件。

答案 1 :(得分:3)

如果排序可观察集合的主要原因是将排序列表中的数据显示给用户而不是出于性能原因(即更快访问),则可以使用CollectionViewSource。 Bea Stollnitz在她的how to use the CollectionViewSource to implement sorting and grouping of collections for the UI博客上有一个很好的描述。

这可能会有所帮助,因为这意味着您不必在可观察集合上实现排序,并担心Robert发送INotifyCollectionChanged所表现出的性能命中。但是,它允许在UI中按排序顺序显示项目。