2009-11-09 21 views
10

Wiem, że istnieje wiele pytań na ten temat. Przeszedłem przez wszystkie, ale nic nie pomaga.Jak sortować kolumnę DataGridView?

Jak sortować, klikając nagłówek kolumny?

Jak zmienić ten kod, aby wykonać zadanie?

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 
} 

Odpowiedz

14

Przypominam, że problemy ze znalezieniem czegoś, co będzie działać, gdy dodałem sortowanie do moich datagrids też. Możesz wdrożyć sortowalną listę powiązań, dodając najpierw do projektu następującą klasę. Jest to implementacja listy implementująca BindingList<T>, dzięki czemu można powiązać z nią datagrid, a także obsługuje sortowanie. Lepszym wyjaśnieniem szczegółów niż mogę dać jest na 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; } 
} 

} 

Mając to na miejscu, jedyne zmiany, które trzeba wprowadzać do kodu, które zostały zamieszczone powyżej jest stworzenie SortableBindingList na podstawie listy i wiąż do listy do sortowania, a nie do standardowej, na przykład:

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 

I to wystarczy, abyś mógł iść.

+0

fajne, to jest to !!! (+ 1A) –

4

Oto blog, który bardzo mi pomógł.

Presenting the SortableBindableList

Ponadto, sprawdź How do I implement automatic sorting of DataGridView? który ma tego przykłady i innej biblioteki.

+1

+1 za link do w pełni funkcjonalnego projektu, który implementuje SortableBindingList - po prostu upuść 2 pliki do własnego projektu. Zauważ, że autor zaktualizował kod nieco na http://www.timvw.be/presenting-the-sortablebindinglistt-take-two/ - wystarczy pobrać plik zip –

+1

Pierwszy link nie jest już ważny ... – Grahamvs

Powiązane problemy