【问题标题】:C# - troubles with sorting datagridviewC# - 排序datagridview的麻烦
【发布时间】:2017-02-23 16:41:01
【问题描述】:

我已经搜索了我的问题的答案。 我已经开发了一个带有一些 datagridviews 的 c# Winforms 程序。

问题是我希望成为能够通过单击列标题对数据网格视图进行排序的用户(我认为这将是标准的......) 但它只是不起作用。

我尝试了 dgv.Sort 方法,但这引发了一个异常,即 datagridview 必须绑定到 IBindingList,但我不知道如何做到这一点,我真的不想重新开发所有内容..

这是我如何填充我的 dgv。

我有一些自定义对象并将它们放入列表中。当此列表完全填充后,我将其设置为 dgv 的数据源。

list.Add(costumobject);
.
.
.
dgv.DataSource = list;

您能告诉我一种使排序功能正常工作的快速方法吗?

亲切的问候,

【问题讨论】:

  • 单击排序按钮-> 排序您的列表-> 放入数据源-> 重新绑定网格
  • 您的问题解决了吗?

标签: c# list sorting datagridview


【解决方案1】:

List<T> 不支持直接排序。

相反,您可以使用 Linq 例程进行排序。

但是,您将需要包括一个排序字段检查,该检查将与您的列数一样长..

不知道你的customobject 类,让我们试试Name 类:

class Name
{
    public string first { get; set; }
    public string last { get; set; }
    public string middle { get; set; }

    public Name (string f, string m, string l)
    {
        first = f; middle = m; last = l;
    }
}

现在让我们编写ColumnHeaderMouseClick 事件:

private void dataGridView1_ColumnHeaderMouseClick(object sender, 
                           DataGridViewCellMouseEventArgs e)
{
    List<Name> names = dataGridView1.DataSource as List<Name>;
    string col = dataGridView2.Columns[e.ColumnIndex].DataPropertyName;
    string order =  " ASC";
    if (dataGridView1.Tag != null) 
        order = dataGridView1.Tag.ToString().Contains(" ASC") ? " DESC" : " ASC";

    dataGridView1.Tag = col + order;

    if (order.Contains(" ASC"))
    names = names.OrderBy(x => col == "first"? x.first 
                             : col == "last" ? x.last : x.middle).ToList();  
    else
    names = names.OrderByDescending(x => col == "first"? x.first : 
                                         col == "last" ? x.last : x.middle).ToList();  

    dataGridView1.DataSource = names;
}

请注意,我将当前排序列和顺序存储在 DGV 的 Tag 中。您可以将其移动到类级别变量或其他位置。不幸的是,无法设置 DGV 的 SortOrder 属性..

【讨论】:

    【解决方案2】:

    创建一个 SortableBindingList 而不是 List。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    
    namespace YourNamespace
    {
        /// <summary>
        /// Provides a generic collection that supports data binding and additionally supports sorting.
        /// See http://msdn.microsoft.com/en-us/library/ms993236.aspx
        /// If the elements are IComparable it uses that; otherwise compares the ToString()
        /// </summary>
        /// <typeparam name="T">The type of elements in the list.</typeparam>
        public class SortableBindingList<T> : BindingList<T> where T : class
        {
            private bool _isSorted;
            private ListSortDirection _sortDirection = ListSortDirection.Ascending;
            private PropertyDescriptor _sortProperty;
    
            /// <summary>
            /// Initializes a new instance of the <see cref="SortableBindingList{T}"/> class.
            /// </summary>
            public SortableBindingList()
            {
            }
    
            /// <summary>
            /// Initializes a new instance of the <see cref="SortableBindingList{T}"/> class.
            /// </summary>
            /// <param name="list">An <see cref="T:System.Collections.Generic.IList`1" /> of items to be contained in the <see cref="T:System.ComponentModel.BindingList`1" />.</param>
            public SortableBindingList(IList<T> list) : base(list)
            {
            }
    
            /// <summary>
            /// Gets a value indicating whether the list supports sorting.
            /// </summary>
            protected override bool SupportsSortingCore
            {
                get { return true; }
            }
    
            /// <summary>
            /// Gets a value indicating whether the list is sorted.
            /// </summary>
            protected override bool IsSortedCore
            {
                get { return _isSorted; }
            }
    
            /// <summary>
            /// Gets the direction the list is sorted.
            /// </summary>
            protected override ListSortDirection SortDirectionCore
            {
                get { return _sortDirection; }
            }
    
            /// <summary>
            /// Gets the property descriptor that is used for sorting the list if sorting is implemented in a derived class; otherwise, returns null
            /// </summary>
            protected override PropertyDescriptor SortPropertyCore
            {
                get { return _sortProperty; }
            }
    
            /// <summary>
            /// Removes any sort applied with ApplySortCore if sorting is implemented
            /// </summary>
            protected override void RemoveSortCore()
            {
                _sortDirection = ListSortDirection.Ascending;
                _sortProperty = null;
                _isSorted = false; //thanks Luca
            }
    
            /// <summary>
            /// Sorts the items if overridden in a derived class
            /// </summary>
            /// <param name="prop"></param>
            /// <param name="direction"></param>
            protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
            {
                _sortProperty = prop;
                _sortDirection = direction;
    
                List<T> list = Items as List<T>;
                if (list == null) return;
                list.Sort(Compare);
                _isSorted = true;
                //fire an event that the list has been changed.
                OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
            }
    
            private int Compare(T lhs, T rhs)
            {
                var result = OnComparison(lhs, rhs);
                //invert if descending
                if (_sortDirection == ListSortDirection.Descending)
                    result = -result;
                return result;
            }
    
            private int OnComparison(T lhs, T rhs)
            {
                object lhsValue = lhs == null ? null : _sortProperty.GetValue(lhs);
                object rhsValue = rhs == null ? null : _sortProperty.GetValue(rhs);
                if (lhsValue == null)
                {
                    return (rhsValue == null) ? 0 : -1; //nulls are equal
                }
    
                if (rhsValue == null)
                {
                    return 1; //first has value, second doesn't
                }
    
                if (lhsValue is IComparable)
                {
                    return ((IComparable)lhsValue).CompareTo(rhsValue);
                }
    
                if (lhsValue.Equals(rhsValue))
                {
                    return 0; //both are the same
                }
    
                //not comparable, compare ToString
                return lhsValue.ToString().CompareTo(rhsValue.ToString());
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

      您是否尝试在更改数据源后刷新数据网格?

      list.Add(costumobject);
      .
      .
      .
      dgv.DataSource = list;
      dgv.Refresh();
      

      【讨论】:

        猜你喜欢
        • 2017-10-13
        • 2012-01-08
        • 2011-05-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-16
        • 1970-01-01
        相关资源
        最近更新 更多