2008-11-11 75 views
2

在應用程序中使用ORM方法通常會導致出現這樣的情景,即您有一組已檢索的對象並希望使用DataGridView在表格視圖中顯示它們。在DataGridViews中顯示對象的集合

在我(有限)的經驗中,使用自定義BindingList綁定到DataGridView的對象集合導致性能差和排序不滿意。我正在尋找這個問題的通用解決方案,以便填充DataGridView並在稍後提取基礎對象時很簡單。

我將描述一個我找到的很好的解決方案,但我正在尋找替代品。

回答

1

我打算在這個答案前加上聲明,說我的經驗是在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; 
    } 

} 
1

Javier Lozano建議將對象集合轉換爲DataTable,然後根據需要將DataRows轉換回對象。他的解決方案使用反射來使其通用。他甚至發佈了code on his blog。我做了一些小的修改,以支持對象中的Nullable類型,這對我來說目前看起來效果很好。

相關問題