Dot-Net
DataGridView 排序,例如 .NET 中的 BindingList<T>
我
BindingList<T>在我的 Windows 窗體中使用了一個包含“IComparable<Contact>”聯繫人對象的列表。現在我希望使用者能夠按網格中顯示的任何列進行排序。MSDN online 上描述了一種方法,它顯示瞭如何實現基於
BindingList<T>允許排序的自定義集合。但是,是不是有一個排序事件或可以在 DataGridView(或者更好的是,在 BindingSource 上)中擷取的東西來使用自定義程式碼對基礎集合進行排序?我不太喜歡 MSDN 描述的方式。另一種方法是我可以輕鬆地將 LINQ 查詢應用於集合。
我非常欣賞Matthias 的簡單和美觀的解決方案。
然而,雖然這為低數據量提供了出色的結果,但在處理大數據量時,由於反射,性能並不是那麼好。
我用一組簡單的數據對象進行了測試,計算了 100000 個元素。按整數類型屬性排序大約需要 1 分鐘。我將進一步詳細介紹的實現將其更改為~200ms。
基本思想是有利於強類型比較,同時保持 ApplySortCore 方法的通用性。下面將通用比較委託替換為對特定比較器的呼叫,在派生類中實現:
SortableBindingList<T> 中的新功能:
protected abstract Comparison<T> GetComparer(PropertyDescriptor prop);ApplySortCore 更改為:
protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction) { List<T> itemsList = (List<T>)this.Items; if (prop.PropertyType.GetInterface("IComparable") != null) { Comparison<T> comparer = GetComparer(prop); itemsList.Sort(comparer); if (direction == ListSortDirection.Descending) { itemsList.Reverse(); } } isSortedValue = true; sortPropertyValue = prop; sortDirectionValue = direction; }現在,在派生類中,必須為每個可排序屬性實現比較器:
class MyBindingList:SortableBindingList<DataObject> { protected override Comparison<DataObject> GetComparer(PropertyDescriptor prop) { Comparison<DataObject> comparer; switch (prop.Name) { case "MyIntProperty": comparer = new Comparison<DataObject>(delegate(DataObject x, DataObject y) { if (x != null) if (y != null) return (x.MyIntProperty.CompareTo(y.MyIntProperty)); else return 1; else if (y != null) return -1; else return 0; }); break; // Implement comparers for other sortable properties here. } return comparer; } } }這個變體需要更多的程式碼,但如果性能是一個問題,我認為值得付出努力。