排序列表与ObservableCollection
我发现我“正在做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 : ObservableCollection { public int Compare (Person a, Person b) { return a.Name.CompareTo(b.Name); } }
可观察集合不实现排序,原因很简单,每当项目从列表中的一个位置移动到另一个位置时,集合就会引发事件。 这对于观看排序算法的动画非常有用,但是对于排序来说,它会很糟糕。
有两种方法可以做到这一点; 它们非常相似,都是通过对可观察集合之外的项进行排序开始的,例如,如果_Fruits
是一个ObservableCollection
,并且你已经为这个排序定义了一个IComparer
,你可以这样做:
var sorted = _Fruits.OrderBy(x => x, new FruitComparer());
这会创建一个新的IEnumerable
,当你迭代它时,它将拥有新顺序的对象。 你可以用两件事做这件事。
一种是创建一个新集合,替换旧集合,并强制UI中的任何项目控件重新绑定到它:
_Fruits = new ObservableCollection(sorted); OnPropertyChanged("Fruits");
(这假设您的类以通常的方式实现INotifyPropertyChanged
。)
另一种是创建一个新的排序列表,然后使用它来移动集合中的项目:
int i = 0; foreach (Fruit f in sorted) { _Fruits.MoveItem(_Fruits.IndexOf(f), i); i++; }
第二种方法是我只会尝试,如果我有一个非常认真的承诺不重新绑定项目控件,因为它将引发大量的收集更改事件。
如果对可观察集合进行排序的主要原因是将排序列表中的数据显示给用户而不是出于性能原因(即更快访问),则可以使用CollectionViewSource。 Bea Stollnitz在她的博客上有一个很好的描述如何使用CollectionViewSource来实现UI的集合的排序和分组 。
这可能有所帮助,因为这意味着您不必在可观察集合上实现排序,并担心Robert指示发送INotifyCollectionChanged的性能命中。 但是,它将允许在UI中按排序顺序显示项目。