解决DataGridView 控件必须绑定到IBindingList才能排序方法

作者:袖梨 2022-06-25

DataGridView使用List做数据源:

List people = new List();
//todo
dataGridView1.DataSource = people;

调用Sort方法排序出错,提示:

引用内容
DataGridView 控件必须绑定到 IBindingList 对象才能排序

我们知道,使用DataTable做数据源时排序是没问题的,所以首先想到的是有没有办法将List转成DataTable?有网友提供了两个扩展方法经测试可行:


public static class DataTableExtensions
{
    ///


    /// List转DataTable
    ///

    ///
    ///
    ///
    public static DataTable ToDataTable(this List list)
    {
        DataTable result = new DataTable();
        List pList = new List();
        Type type = typeof(T);
        Array.ForEach(type.GetProperties(), prop => { pList.Add(prop); result.Columns.Add(prop.Name, prop.PropertyType); });
        foreach (var item in list)
        {
            DataRow row = result.NewRow();
            pList.ForEach(p => row[p.Name] = p.GetValue(item, null));
            result.Rows.Add(row);
        }
        return result;
    }

    ///


    /// DataTable转List
    ///

    ///
    ///
    ///
    public static List ToList(this DataTable table) where T : class, new()
    {
        List result = new List();
        List pList = new List();
        Type type = typeof(T);
        Array.ForEach(type.GetProperties(), prop => { if (table.Columns.IndexOf(prop.Name) != -1) pList.Add(prop); });
        foreach (DataRow row in table.Rows)
        {
            T obj = new T();
            pList.ForEach(prop => { if (row[prop.Name] != DBNull.Value) prop.SetValue(obj, row[prop.Name], null); });
            result.Add(obj);
        }
        return result;
    }
}


dataGridView1.DataSource = people.ToDataTable();

另一个思路是根据错误信息实现自己的IBindingList对象,也有网友提供了方法:


///


/// 提供支持数据绑定的泛型集合
///

///
public class BindingCollection : BindingList
{
    private bool _isSortedCore = true;
    private ListSortDirection _sortDirectionCore = ListSortDirection.Ascending;
    private PropertyDescriptor _sortPropertyCore = null;

    ///


    /// 是否已排序
    ///

    protected override bool IsSortedCore
    {
        get { return _isSortedCore; }
    }
    ///
    /// 获取列表的排序方向
    ///

    protected override ListSortDirection SortDirectionCore
    {
        get { return _sortDirectionCore; }
    }
    ///
    /// 获取用于对列表排序的属性说明符
    ///

    protected override PropertyDescriptor SortPropertyCore
    {
        get { return _sortPropertyCore; }
    }
    ///
    /// 是否支持排序
    ///

    protected override bool SupportsSortingCore
    {
        get { return true; }
    }
    ///
    /// 是否支持搜索
    ///

    protected override bool SupportsSearchingCore
    {
        get { return true; }
    }

    ///


    /// 构造函数
    ///

    public BindingCollection()
    { }

    ///


    /// 构造函数
    ///

    ///
    public BindingCollection(IList list)
        : base(list)
    { }

    ///


    /// 对项排序
    ///

    ///
    ///
    protected override void ApplySortCore(PropertyDescriptor property, ListSortDirection direction)
    {
        List items = this.Items as List;

        if (items != null)
        {
            ObjectPropertyCompare pc = new ObjectPropertyCompare(property, direction);
            items.Sort(pc);
            _isSortedCore = true;
            _sortDirectionCore = direction;
            _sortPropertyCore = property;
        }
        else
        {
            _isSortedCore = false;
        }

        this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
    }

    ///


    /// 移除排序
    ///

    protected override void RemoveSortCore()
    {
        _isSortedCore = false;
        this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
    }
}

public class ObjectPropertyCompare : IComparer
{
    ///


    /// 属性
    ///

    public PropertyDescriptor Property { get; set; }
    ///
    /// 排序方向
    ///

    public ListSortDirection Direction { get; set; }

    ///


    /// 构造函数
    ///

    public ObjectPropertyCompare()
    { }

    ///


    /// 构造函数
    ///

    ///
    ///
    public ObjectPropertyCompare(PropertyDescriptor property, ListSortDirection direction)
    {
        Property = property;
        Direction = direction;
    }

    ///


    /// 比较两个对象
    ///

    ///
    ///
    ///
    public int Compare(T x, T y)
    {
        object xValue = x.GetType().GetProperty(Property.Name).GetValue(x, null);
        object yValue = y.GetType().GetProperty(Property.Name).GetValue(y, null);

        int returnValue;

        if (xValue == null && yValue == null)
        {
            returnValue = 0;
        }
        else if (xValue == null)
        {
            returnValue = -1;
        }
        else if (yValue == null)
        {
            returnValue = 1;
        }
        else if (xValue is IComparable)
        {
            returnValue = ((IComparable)xValue).CompareTo(yValue);
        }
        else if (xValue.Equals(yValue))
        {
            returnValue = 0;
        }
        else
        {
            returnValue = xValue.ToString().CompareTo(yValue.ToString());
        }

        if (Direction == ListSortDirection.Ascending)
        {
            return returnValue;
        }
        else
        {
            return returnValue * -1;
        }
    }
}


dataGridView1.DataSource = new BindingCollection(people);

相关文章

精彩推荐