2010-02-25 70 views
4

我发现我是“做WPF错误”,令人沮丧地必须彻底检修我的代码。排序列表与ObservableCollection

我怎么能转换如下:

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); 
    } 
} 
+1

我不确定“做WPF错误”的评论。仅仅因为你在做WPF,所有东西都不(也不应该)必须是可观察的集合。如果你不需要对集合中的变化做出反应,那么把它变成一个可观察的集合是很浪费的。 – 2010-02-25 01:13:43

+0

哦,我明白了。这就是为什么我首先使用列表。问题是我需要对集​​合中的更改作出反应 – baron 2010-02-25 01:46:35

回答

14

观察集合没有实现排序,原因很简单尝试,每一次从一个位置的项目移动列表中的另一集合引发一个事件。这对于观看排序算法的动画效果会非常好,但它会让人觉得很分类。

有两种方法可以做到这一点;它们非常相似,并且都是通过对其可观察集合之外的项目进行排序开始的,例如,如果_FruitsObservableCollection<Fruit>,以及您所定义的IComparer<Fruit>的排序,你会怎么做:

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

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

一种方法是建立一个新的集合,取代旧的,并且强迫任何项目控制(S)在UI重新绑定到它:

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

(假设你的类中实现INotifyPropertyChanged 。通常的方式)

另一种是创建一个新的排序列表,然后用它来移动您的收藏中的项目:

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

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

+0

如果您要绑定到集合,最好像在mattythomas2000中所建议的那样,在CollectionView上添加排序,因为无论如何都会隐式使用CollectionView。 – Grokys 2010-02-25 19:59:57

3

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

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