【问题标题】:Using SortableBindingList<T> - DataGridView doesn't automatically sort on changes使用 SortableBindingList<T> - DataGridView 不会自动对更改进行排序
【发布时间】:2017-01-25 00:35:00
【问题描述】:

我正在构建一个 Windows 窗体应用程序,它显示一个自定义类 Record 对象,并按照它们在我的 SortableBindingList&lt;Record&gt; record_list 中的存在时间对它们进行排序。当我启动我的程序时,为了测试,我已经在这个列表中加载了一些“虚拟”记录。

SortableBindingList&lt;T&gt; 取自 here

public partial class Form1 : Form
{
    public SortableBindingList<Record> record_list = new SortableBindingList<Record> { };
    public static DataGridViewCellStyle style = new DataGridViewCellStyle();
    public Form1()
    {
        InitializeComponent();
        dataGridView.DataSource = record_list;
        FillData(); //Temporary function to insert dummy data for demo.
        dataGridView.CellFormatting += new System.Windows.Forms.DataGridViewCellFormattingEventHandler(this.cell_formatting);
        this.Controls.Add(dataGridView);
        this.dataGridView.RowHeadersVisible = false;
        this.dataGridView.Sort(this.dataGridView.Columns["UserName"], ListSortDirection.Ascending);

        start_timer();                 
    }

添加“新”数据之前的结果(注意:这是自动按字母顺序排列的,特别是按字母顺序输入列表):

添加数据后的结果:

最后,点击“用户名”标题后的结果:

那么,每次更新我的数据源时,我必须强制进行排序吗?如果是这样,我该如何以这种方式调用排序?

提前感谢您的帮助!

【问题讨论】:

  • 没有标准的SortableBindingList&lt;T&gt;类,你指的是哪一个?
  • 这是一个自定义类,取自:stackoverflow.com/questions/23661195/…
  • 嗯,这就是它不起作用的原因 - 这是一个非常基本的实现,典型的 SO 回答。

标签: c# .net winforms datagridview bindinglist


【解决方案1】:

您需要在列表更改时应用排序。

SortableBindingList&lt;T&gt; 需要在列表中进行一些更改时进行一些更改以保持列表排序。这是我所做的更改的完整代码。

注意BindingListOnListChanged方法在添加和删除项目后会被自动调用。但是如果你需要OnListChanged在更改项目属性后也运行,你应该为你的模型类实现INotifyPropertyChanged

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
public class SortableBindingList<T> : BindingList<T>
{
    private bool isSortedValue;
    ListSortDirection sortDirectionValue;
    PropertyDescriptor sortPropertyValue;
    public SortableBindingList() : base() { }
    public SortableBindingList(IList<T> list) : base(list) { }
    protected override void ApplySortCore(PropertyDescriptor prop,
        ListSortDirection direction)
    {
        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;
            sorting = true;
            this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
            sorting = false;
        }
        else
        {
            throw new NotSupportedException("Cannot sort by " + prop.Name +
                ". This" + prop.PropertyType.ToString() +
                " does not implement IComparable");
        }
    }
    bool sorting = false;
    protected override PropertyDescriptor SortPropertyCore
    {
        get { return sortPropertyValue; }
    }
    protected override ListSortDirection SortDirectionCore
    {
        get { return sortDirectionValue; }
    }
    protected override bool SupportsSortingCore
    {
        get { return true; }
    }
    protected override bool IsSortedCore
    {
        get { return isSortedValue; }
    }
    protected override void RemoveSortCore()
    {
        isSortedValue = false;
        sortPropertyValue = null;
    }
    protected override void OnListChanged(ListChangedEventArgs e)
    {
        if (!sorting && sortPropertyValue != null)
            ApplySortCore(sortPropertyValue, sortDirectionValue);
        else
            base.OnListChanged(e);
    }
}

【讨论】:

    猜你喜欢
    • 2017-09-22
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 2015-03-25
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多