2009-11-09 101 views
10

我知道這個話題有很多問題。我經歷了所有這些,但似乎沒有任何幫助。如何對數據綁定DataGridView列進行排序?

如何通過單擊列標題進行排序?

我應該如何修改此代碼來完成這項工作?

public partial class Form1 : Form 
{ 

    public Form1() 
    { 

     List<MyClass> list = new List<MyClass>(); 
     list.Add(new MyClass("Peter", 1202)); 
     list.Add(new MyClass("James", 292)); 
     list.Add(new MyClass("Bond", 23)); 

     BindingSource bs = new BindingSource(); 
     bs.DataSource = list; 

     DataGridView dg = new DataGridView(); 

     DataGridViewTextBoxColumn c = new DataGridViewTextBoxColumn(); 
     c.Name = "name"; 
     c.DataPropertyName = "Name"; 
     dg.Columns.Add(c); 

     c = new DataGridViewTextBoxColumn(); 
     c.Name = "number"; 
     c.DataPropertyName = "Number"; 
     dg.Columns.Add(c); 

     dg.DataSource = bs; 

     this.Controls.Add((Control)dg); 

    } 

} 

class MyClass:IComparable<MyClass> 
{ 
    public string Name { get; set; } 
    public int Number { get; set; } 

    public MyClass(){} 

    public MyClass(string name,int number) 
    { 
     Name = name; 
     Number = number; 
    } 

    public override string ToString() 
    { 
     return string.Format("{0}:{1}",Name,Number); 
    } 

    #region IComparable<MyClass> Members 

    public int CompareTo(MyClass other) 
    { 
     return Name.CompareTo(other.Name); 
    } 

    #endregion 
} 

回答

14

我記得當我向我的數據網格中添加排序功能時,發現有問題可以解決。您可以通過首先將以下類添加到項目中來實現可排序的可綁定列表。它是一個實現BindingList<T>的列表實現,以便您可以綁定您的數據網格,並且它還支持排序。細節比我能給出更好的解釋是MSDN here

public class SortableBindingList<T> : BindingList<T> 
{ 
    private ArrayList sortedList; 
    private ArrayList unsortedItems; 
    private bool isSortedValue; 

public SortableBindingList() 
{ 
} 

public SortableBindingList(IList<T> list) 
{ 
    foreach (object o in list) 
    { 
     this.Add((T)o); 
    } 
} 

protected override bool SupportsSearchingCore 
{ 
    get 
    { 
     return true; 
    } 
} 

protected override int FindCore(PropertyDescriptor prop, object key) 
{ 
    PropertyInfo propInfo = typeof(T).GetProperty(prop.Name); 
    T item; 

    if (key != null) 
    { 
     for (int i = 0; i < Count; ++i) 
     { 
      item = (T)Items[i]; 
      if (propInfo.GetValue(item, null).Equals(key)) 
       return i; 
     } 
    } 
    return -1; 
} 

public int Find(string property, object key) 
{ 
    PropertyDescriptorCollection properties = 
     TypeDescriptor.GetProperties(typeof(T)); 
    PropertyDescriptor prop = properties.Find(property, true); 

    if (prop == null) 
     return -1; 
    else 
     return FindCore(prop, key); 
} 

protected override bool SupportsSortingCore 
{ 
    get { return true; } 
} 


protected override bool IsSortedCore 
{ 
    get { return isSortedValue; } 
} 

ListSortDirection sortDirectionValue; 
PropertyDescriptor sortPropertyValue; 

protected override void ApplySortCore(PropertyDescriptor prop, 
    ListSortDirection direction) 
{ 
    sortedList = new ArrayList(); 

    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<T> 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; 
     this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); 

    } 
    else 
    { 
     throw new NotSupportedException("Cannot sort by " + prop.Name + 
      ". This" + prop.PropertyType.ToString() + 
      " does not implement IComparable"); 
    } 
} 

protected override void RemoveSortCore() 
{ 
    int position; 
    object temp; 

    if (unsortedItems != null) 
    { 
     for (int i = 0; i < unsortedItems.Count;) 
     { 
      position = this.Find("LastName", 
       unsortedItems[i].GetType(). 
       GetProperty("LastName").GetValue(unsortedItems[i], null)); 
      if (position > 0 && position != i) 
      { 
       temp = this[i]; 
       this[i] = this[position]; 
       this[position] = (T)temp; 
       i++; 
      } 
      else if (position == i) 
       i++; 
      else 
       unsortedItems.RemoveAt(i); 
     } 
     isSortedValue = false; 
     OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1)); 
    } 
} 

public void RemoveSort() 
{ 
    RemoveSortCore(); 
} 
protected override PropertyDescriptor SortPropertyCore 
{ 
    get { return sortPropertyValue; } 
} 

protected override ListSortDirection SortDirectionCore 
{ 
    get { return sortDirectionValue; } 
} 

} 

有了到位,只有你需要對你在上面發佈的代碼的變化是基於你的清單上建立一個SortableBindingList和綁定到可排序列表,而不是標準列表,如下所示:

List<MyClass> list = new List<MyClass>(); 
list.Add(new MyClass("Peter", 1202)); 
list.Add(new MyClass("James", 292)); 
list.Add(new MyClass("Bond", 23)); 

// Added sortable list... 
SortableBindingList<MyClass> sortableList = new SortableBindingList<MyClass>(list); 

BindingSource bs = new BindingSource(); 
bs.DataSource = sortableList; // Bind to the sortable list 

這樣就足以讓您走了。

+0

很酷這就是它! (+ 1A) – 2009-11-09 09:25:54

4

這裏是真正幫助我的博客文章。

Presenting the SortableBindableList

此外,檢查出How do I implement automatic sorting of DataGridView?擁有的這一點,另一個庫的例子。

+1

+1,用於鏈接到實現SortableBindingList的全功能項目 - 只需將2個文件放入您自己的項目中即可。請注意,作者在http://www.timvw.be/presenting-the-sortablebindinglistt-take-two/上更新了代碼 - 只需下載zip文件 – 2009-12-29 20:18:25

+1

第一個鏈接不再有效... – Grahamvs 2017-04-06 17:56:17

相關問題