2016-10-14 77 views
0

我已經搜索了我的屁股爲我的問題的答案。 我已經開發了一個c#Winforms程序與幾個datagridviews。C# - 排序datagridview的問題

問題是,我想成爲用戶能夠通過點擊columnheader排序datagridview(我認爲這將是標準的...) 但它只是不工作。

我試過dgv.Sort法,但這拋出在DataGridView必須綁定到IBindingList的一個例外,但我不知道該怎麼做,我真的不想redevelope一切..

以下是我如何填充我的dgv。

我有一定的自定義對象,並把它們放到一個列表中。當這個列表完全填充時,我將它設置爲dgv的數據源。

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

請問能否告訴我一種快速的方法來使排序功能起作用?

親切的問候,

+0

點擊排序按鈕 - >排序的列表 - >說就是數據源 - >重新綁定網格 – mybirthname

+0

您已經解決你的問題? – TaW

回答

0

您是否嘗試在更改數據源後刷新數據網格?

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

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屬性無法設置。

1

創建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()); 
     } 
    } 
}