使用SortableBindingList – DataGridView不会自动对更改进行排序

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

SortableBindingList已从此处获取 。

 public partial class Form1 : Form { public SortableBindingList record_list = new SortableBindingList { }; 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(); } 

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

在此处输入图像描述

添加数据后的结果:

在此处输入图像描述

最后,单击“UserName”标题后的结果:

在此处输入图像描述

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

感谢您的帮助!

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

SortableBindingList需要进行一些更改,以便在列表中进行某些更改时对列表进行排序。 以下是我所做的更改的完整代码。

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

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; public class SortableBindingList : BindingList { private bool isSortedValue; ListSortDirection sortDirectionValue; PropertyDescriptor sortPropertyValue; public SortableBindingList() : base() { } public SortableBindingList(IList 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 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); } }