代码之家  ›  专栏  ›  技术社区  ›  Cory Engebretson

在DataGridView中显示对象集合

  •  2
  • Cory Engebretson  · 技术社区  · 17 年前

    在应用程序中使用ORM方法通常会导致这样一种情况,即您有一组已检索的对象,并且希望使用DataGridView在表格视图中显示它们。

    根据我(有限)的经验,使用自定义BindingList将对象集合绑定到DataGridView会导致性能低下和排序不理想。我正在寻找这个问题的通用解决方案,这样就可以直接填充DataGridView并在以后提取底层对象。

    我将描述我找到的一个好的解决方案,但我正在寻找替代方案。

    2 回复  |  直到 17 年前
        1
  •  1
  •   asponge    17 年前

    在回答这个问题之前,我会说我的经验是在2.0框架领域。较新的框架可能会提供其他解决方案。

    下面是BindingList派生的类,它支持双向排序和List的其他有用功能。我不能把财产比较分类归功于我。不久前我在一篇文章中发现了这一点,但现在我看到它遍布互联网,所以很遗憾我无法引用原始来源。

    另一种选择是BindingListView: http://blw.sourceforge.net . 此类允许您创建列表集合的视图,就像使用DataTable对象一样,包括定义筛选器和排序的功能。

    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;
        }
    
    }
    
        2
  •  1
  •   Cory Engebretson    17 年前

    Javier Lozano建议将对象集合转换为DataTable,然后根据需要将DataRows转换回对象。他的解决方案使用反射使其通用。他甚至发布了 code on his blog . 我做了一些小的修改,以支持对象中的可空类型,到目前为止,这似乎对我很有效。