在應用程序中使用ORM方法通常會導致出現這樣的情景,即您有一組已檢索的對象並希望使用DataGridView在表格視圖中顯示它們。在DataGridViews中顯示對象的集合
在我(有限)的經驗中,使用自定義BindingList綁定到DataGridView的對象集合導致性能差和排序不滿意。我正在尋找這個問題的通用解決方案,以便填充DataGridView並在稍後提取基礎對象時很簡單。
我將描述一個我找到的很好的解決方案,但我正在尋找替代品。
在應用程序中使用ORM方法通常會導致出現這樣的情景,即您有一組已檢索的對象並希望使用DataGridView在表格視圖中顯示它們。在DataGridViews中顯示對象的集合
在我(有限)的經驗中,使用自定義BindingList綁定到DataGridView的對象集合導致性能差和排序不滿意。我正在尋找這個問題的通用解決方案,以便填充DataGridView並在稍後提取基礎對象時很簡單。
我將描述一個我找到的很好的解決方案,但我正在尋找替代品。
我打算在這個答案前加上聲明,說我的經驗是在2.0框架域中。較新的框架可能會提供其他解決方案。
下面是一個BindingList派生類,它支持List的雙向排序和其他有用的功能。我無法對PropertyComparer排序進行評分。我在一篇文章中發現了這一點,但現在我發現它遍佈互聯網,所以我不幸引用了原始資料。
另一種選擇是BindingListView:http://blw.sourceforge.net。該類允許您創建List集合的視圖,就像使用DataTable對象一樣,包括定義Filter和Sort的功能。
public class UsefulBindingList<T> : BindingList<T>
{
private bool _isSorted = false;
private ListSortDirection _sortDirection;
private PropertyDescriptor _sortProperty;
protected override bool SupportsSortingCore
{
get { return true; }
}
protected override bool IsSortedCore
{
get { return _isSorted; }
}
protected override ListSortDirection SortDirectionCore
{
get { return _sortDirection; }
}
protected override PropertyDescriptor SortPropertyCore
{
get { return _sortProperty; }
}
public void AddRange(IEnumerable<T> collection)
{
IEnumerator<T> e = collection.GetEnumerator();
while (e.MoveNext())
{
this.Add(e.Current);
}
}
public T Find(Predicate<T> match)
{
List<T> items = this.Items as List<T>;
if (items != null)
return items.Find(match);
else
return default(T);
}
public int FindIndex(Predicate<T> match)
{
List<T> items = this.Items as List<T>;
if (items != null)
return items.FindIndex(match);
else
return -1;
}
public bool Exists(Predicate<T> match)
{
List<T> items = this.Items as List<T>;
return items.Exists(match);
}
public void Sort()
{
List<T> items = this.Items as List<T>;
if (items != null)
items.Sort();
}
public void Sort(Comparison<T> comparison)
{
List<T> items = this.Items as List<T>;
if (items != null)
items.Sort(comparison);
}
public void Sort(IComparer<T> comparer)
{
List<T> items = this.Items as List<T>;
if (items != null)
items.Sort(comparer);
}
protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
_sortProperty = prop;
_sortDirection = direction;
List<T> items = this.Items as List<T>;
if (items != null)
{
PropertyComparer<T> pc = new PropertyComparer<T>(prop, direction);
items.Sort(pc);
_isSorted = true;
}
else
{
_isSorted = false;
}
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
protected override void RemoveSortCore()
{
_isSorted = false;
}
}
public class PropertyComparer<T> : IComparer<T>
{
private ListSortDirection _sortDirection;
private PropertyDescriptor _property;
public PropertyComparer(PropertyDescriptor property, ListSortDirection direction)
{
_property = property;
_sortDirection = direction;
}
public int Compare(T x, T y)
{
int rv = 0;
object vx = _property.GetValue(x);
object vy = _property.GetValue(y);
rv = System.Collections.Comparer.Default.Compare(vx, vy);
if (_sortDirection == ListSortDirection.Descending)
rv = -rv;
return rv;
}
}
Javier Lozano建議將對象集合轉換爲DataTable,然後根據需要將DataRows轉換回對象。他的解決方案使用反射來使其通用。他甚至發佈了code on his blog。我做了一些小的修改,以支持對象中的Nullable類型,這對我來說目前看起來效果很好。