WinForms:DataGridView – 程序化排序

我有一个带有datagridview的表单。 dataGridView绑定到BindingSource:

public class Address { public string State { get; set; } public string City { get; set; } public string Street { get; set; } } this.addressBindingSource.DataSource = typeof(Address); this.dataGridView1.DataSource = this.addressBindingSource; 

我像这样填写DataSource

  addressBindingSource.DataSource = new BindingList
{ new Address {State = "S1", City = "C1", Street = "S1"}, new Address {State = "S1", City = "C1", Street = "S2"}, new Address {State = "S1", City = "C1", Street = "S3"}, new Address {State = "S1", City = "C2", Street = "S4"}, new Address {State = "S1", City = "C2", Street = "S5"}, new Address {State = "S1", City = "C2", Street = "S6"}, };

我正在尝试为此datagridview启用排序。 我将SortMode设置为Programmatic用于dataGridView1的所有列。 我为ColumnHeaderMouseClick添加了一个事件处理程序:

  private Dictionary columnIndexPropertyNameDictionary = new Dictionary { {0, "State"}, {1, "City"}, {2, "Street"}, }; private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) { if (e.ColumnIndex < 0) return; for (int i = 0; i < dataGridView1.Columns.Count; i++) { if (i == e.ColumnIndex) continue; dataGridView1.Columns[i].HeaderCell.SortGlyphDirection = SortOrder.None; } var column = dataGridView1.Columns[e.ColumnIndex]; if (column.SortMode != DataGridViewColumnSortMode.Programmatic) return; var sortGlyphDirection = column.HeaderCell.SortGlyphDirection; switch (sortGlyphDirection) { case SortOrder.None: case SortOrder.Ascending: addressBindingSource.Sort = columnIndexPropertyNameDictionary[e.ColumnIndex] + " ASC"; column.HeaderCell.SortGlyphDirection = SortOrder.Descending; break; case SortOrder.Descending: addressBindingSource.Sort = columnIndexPropertyNameDictionary[e.ColumnIndex] + " DESC"; column.HeaderCell.SortGlyphDirection = SortOrder.Ascending; break; } } 

排序仍然不起作用。 我究竟做错了什么?

问题是开箱即用的BindingList不支持排序! 我知道 – 听起来很蠢,但就是这样。

您需要实现自己的SortableBindingList。 代码的示例如下。

这段代码来自这里 ,我没有时间仔细检查。 如果它不起作用然后google术语SortableBindingList,有很多实现。

 public class SortableBindingList : BindingList { private bool m_Sorted = false; private ListSortDirection m_SortDirection = ListSortDirection.Ascending; private PropertyDescriptor m_SortProperty = null; protected override bool SupportsSortingCore { get { return true; } } protected override bool IsSortedCore { get { return m_Sorted; } } protected override ListSortDirection SortDirectionCore { get { return m_SortDirection; } } protected override PropertyDescriptor SortPropertyCore { get { return m_SortProperty; } } protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction) { m_SortDirection = direction; m_SortProperty = prop; var listRef = this.Items as List; if (listRef == null) return; var comparer = new SortComparer(prop, direction); listRef.Sort(comparer); OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); } } 

我在添加新行时使用这个简单的函数:

 dataGridViewResult.Sort(dataGridViewResult.Columns[0], ListSortDirection.Descending); 
 private void sortButton_Click(object sender, System.EventArgs e) { // Check which column is selected, otherwise set NewColumn to null. DataGridViewColumn newColumn = dataGridView1.Columns.GetColumnCount( DataGridViewElementStates.Selected) == 1 ? dataGridView1.SelectedColumns[0] : null; DataGridViewColumn oldColumn = dataGridView1.SortedColumn; ListSortDirection direction; // If oldColumn is null, then the DataGridView is not currently sorted. if (oldColumn != null) { // Sort the same column again, reversing the SortOrder. if (oldColumn == newColumn && dataGridView1.SortOrder == SortOrder.Ascending) { direction = ListSortDirection.Descending; } else { // Sort a new column and remove the old SortGlyph. direction = ListSortDirection.Ascending; oldColumn.HeaderCell.SortGlyphDirection = SortOrder.None; } } else { direction = ListSortDirection.Ascending; } // If no column has been selected, display an error dialog box. if (newColumn == null) { MessageBox.Show("Select a single column and try again.", "Error: Invalid Selection", MessageBoxButtons.OK, MessageBoxIcon.Error); } else { dataGridView1.Sort(newColumn, direction); newColumn.HeaderCell.SortGlyphDirection = direction == ListSortDirection.Ascending ? SortOrder.Ascending : SortOrder.Descending; } } 

有一种更简单的方法。 您必须设置列的数据类型,如下所示:

 private void DataGridView1_ColumnAdded(object sender, DataGridViewColumnEventArgs e) { if (e.Column.Index == 0) { e.Column.ValueType = typeof(int); e.Column.CellTemplate.ValueType = typeof(int); } } 

或者如果您具有列的对象名称:

 ColumnName.ValueType = typeof(int);