2016-10-14 2 views
0

私は自分の問題の答えを探していました。 私はいくつかのdatagridviewを持つc#Winformsプログラムを開発しました。C# - sorting with dataagridview

問題は、ユーザーがcolumnheaderをクリックしてデータグリッドビューを並べ替えることができるということです(私はこれが標準であると思っていました...) しかし、それはうまく機能しません。

私は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を作成します。入れ

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