显示DataGridViews中的对象集合

时间:2008-11-11 17:36:53

标签: c# .net

在应用程序中使用ORM方法通常会导致您拥有一组已检索到的对象并希望使用DataGridView在表格视图中显示这些对象的情况。

在我的(有限)体验中,使用自定义BindingList将对象集合绑定到DataGridView导致性能不佳和排序不令人满意。我正在寻找这个问题的通用解决方案,这样可以直接填充DataGridView,并在以后提取底层对象。

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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

我将在这个答案前面加上我的经验在2.0 Framework域内的陈述。较新的框架可能会提供其他解决方案。

下面是一个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;
    }

}