2008-11-11 81 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类型,这对我来说目前看起来效果很好。

相关问题