【问题标题】:How to sort databound DataGridView column?如何对数据绑定的 DataGridView 列进行排序?
【发布时间】:2010-12-14 13:16:22
【问题描述】:

我知道关于这个话题有很多问题。我已经经历了所有这些,但似乎没有任何帮助。

如何通过点击列标题进行排序?

我应该如何修改这段代码来完成这项工作?

public partial class Form1 : Form
{

    public Form1()
    {

        List<MyClass> list = new List<MyClass>();
        list.Add(new MyClass("Peter", 1202));
        list.Add(new MyClass("James", 292));
        list.Add(new MyClass("Bond", 23));

        BindingSource bs = new BindingSource();
        bs.DataSource = list;

        DataGridView dg = new DataGridView();

        DataGridViewTextBoxColumn c = new DataGridViewTextBoxColumn();
        c.Name = "name";
        c.DataPropertyName = "Name";
        dg.Columns.Add(c);

        c = new DataGridViewTextBoxColumn();
        c.Name = "number";
        c.DataPropertyName = "Number";
        dg.Columns.Add(c);

        dg.DataSource = bs;

        this.Controls.Add((Control)dg);

    }

}

class MyClass:IComparable<MyClass>
{
    public string Name { get; set; }
    public int Number { get; set; }

    public MyClass(){}

    public MyClass(string name,int number)
    {
        Name = name;
        Number = number;
    }

    public override string ToString()
    {
        return string.Format("{0}:{1}",Name,Number);
    }

    #region IComparable<MyClass> Members

    public int CompareTo(MyClass other)
    {
        return Name.CompareTo(other.Name);
    }

    #endregion
}

【问题讨论】:

    标签: c# winforms datagridview


    【解决方案1】:

    我记得当我将排序添加到我的数据网格时,我也遇到了一些问题。您可以通过首先将以下类添加到您的项目来实现可排序的可绑定列表。它是一个实现BindingList&lt;T&gt; 的列表实现,因此您可以将您的数据网格绑定到它,并且它还支持排序。 MSDN here

    对细节的解释比我能给出的更好
    public class SortableBindingList<T> : BindingList<T>
    {
        private ArrayList sortedList;
        private ArrayList unsortedItems;
        private bool isSortedValue;
    
    public SortableBindingList()
    {
    }
    
    public SortableBindingList(IList<T> list)
    {
        foreach (object o in list)
        {
            this.Add((T)o);
        }
    }
    
    protected override bool SupportsSearchingCore
    {
        get
        {
            return true;
        }
    }
    
    protected override int FindCore(PropertyDescriptor prop, object key)
    {
        PropertyInfo propInfo = typeof(T).GetProperty(prop.Name);
        T item;
    
        if (key != null)
        {
           for (int i = 0; i < Count; ++i)
            {
                item = (T)Items[i];
                if (propInfo.GetValue(item, null).Equals(key))
                    return i;
            }
        }
        return -1;
    }
    
    public int Find(string property, object key)
    {
        PropertyDescriptorCollection properties =
            TypeDescriptor.GetProperties(typeof(T));
        PropertyDescriptor prop = properties.Find(property, true);
    
        if (prop == null)
            return -1;
        else
            return FindCore(prop, key);
    }
    
    protected override bool SupportsSortingCore
    {
        get { return true; }
    }
    
    
    protected override bool IsSortedCore
    {
        get { return isSortedValue; }
    }
    
    ListSortDirection sortDirectionValue;
    PropertyDescriptor sortPropertyValue;
    
    protected override void ApplySortCore(PropertyDescriptor prop,
        ListSortDirection direction)
    {
        sortedList = new ArrayList();
    
       Type interfaceType = prop.PropertyType.GetInterface("IComparable");
    
        if (interfaceType == null && prop.PropertyType.IsValueType)
        {
            Type underlyingType = Nullable.GetUnderlyingType(prop.PropertyType);
    
             if (underlyingType != null)
            {
                interfaceType = underlyingType.GetInterface("IComparable");
            }
        }
    
        if (interfaceType != null)
        {
            sortPropertyValue = prop;
            sortDirectionValue = direction;
    
            IEnumerable<T> query = base.Items;
            if (direction == ListSortDirection.Ascending)
            {
                query = query.OrderBy(i => prop.GetValue(i));
            }
            else
            {
                query = query.OrderByDescending(i => prop.GetValue(i));
            }
            int newIndex = 0;
            foreach (object item in query)
            {
                this.Items[newIndex] = (T)item;
                newIndex++;
            }
            isSortedValue = true;
            this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
    
        }
        else
        {
            throw new NotSupportedException("Cannot sort by " + prop.Name +
                ". This" + prop.PropertyType.ToString() +
                " does not implement IComparable");
        }
    }
    
    protected override void RemoveSortCore()
    {
        int position;
        object temp;
    
        if (unsortedItems != null)
        {
            for (int i = 0; i < unsortedItems.Count; )
            {
                position = this.Find("LastName",
                    unsortedItems[i].GetType().
                    GetProperty("LastName").GetValue(unsortedItems[i], null));
                if (position > 0 && position != i)
                {
                    temp = this[i];
                    this[i] = this[position];
                    this[position] = (T)temp;
                    i++;
                }
                else if (position == i)
                    i++;
                else
                    unsortedItems.RemoveAt(i);
            }
            isSortedValue = false;
            OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
        }
    }
    
    public void RemoveSort()
    {
        RemoveSortCore();
    }
    protected override PropertyDescriptor SortPropertyCore
    {
        get { return sortPropertyValue; }
    }
    
    protected override ListSortDirection SortDirectionCore
    {
        get { return sortDirectionValue; }
    }
    
    }
    

    有了这些,您需要对上面发布的代码进行的唯一更改是根据您的列表创建一个 SortableBindingList 并绑定到可排序列表,而不是标准列表,如下所示:

    List<MyClass> list = new List<MyClass>();
    list.Add(new MyClass("Peter", 1202));
    list.Add(new MyClass("James", 292));
    list.Add(new MyClass("Bond", 23));
    
    // Added sortable list...
    SortableBindingList<MyClass> sortableList = new SortableBindingList<MyClass>(list);
    
    BindingSource bs = new BindingSource();
    bs.DataSource = sortableList;   // Bind to the sortable list
    

    这足以让你继续前进。

    【讨论】:

    • 这个例子真的很棒!非常感谢!
    【解决方案2】:

    这是真正帮助我的博客文章。

    Presenting the SortableBindableList

    另外,请查看How do I implement automatic sorting of DataGridView?,其中包含此库和另一个库的示例。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-21
    • 1970-01-01
    • 2012-04-27
    • 1970-01-01
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多