2011-04-18 12 views
3

我有一个DataGridView的表单。的dataGridView被绑定到的BindingSource:WinForms:DataGridView - 编程排序

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<Address> 
    { 
     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的。对于dataGridView1的所有列,我将SortMode设置为Programmatic。我加入的事件处理程序ColumnHeaderMouseClick

private Dictionary<int, string> columnIndexPropertyNameDictionary = new Dictionary<int, string> 
     { 
      {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; 
    } 
} 

排序仍然无法正常工作。我究竟做错了什么?

+0

我注意到'addressBindingSource.SupportsSorting = false'。这是为什么? – StuffHappens 2011-04-18 09:28:45

回答

6

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

你需要实现你自己的SortableBindingList。下面是一个代码示例。

此代码来自here,我没有时间仔细检查。如果它不起作用,那么谷歌术语SortableBindingList,那里有批次的实现。

public class SortableBindingList<t> : BindingList<t> 
{ 
    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<t>; 
     if (listRef == null) 
      return; 
     var comparer = new SortComparer<t>(prop, direction); 

     listRef.Sort(comparer); 

     OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); 
    } 
} 
+0

+1为SortableBindingList。最后,我正在朝着排序的方向前进。 – 2011-11-23 07:18:32

2
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; 
    } 
} 
0

还有一个更简单的方法。 必须设置列的数据类型是这样的:

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); 
2

我使用这个简单的命令时添加新行:

dataGridViewResult.Sort(dataGridViewResult.Columns [0],ListSortDirection.Descending);

+0

感谢buddy ..这是最简单的.. – 2013-12-28 22:31:43