2010-02-25 73 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中以排序順序顯示項目。