2009-11-09 5 views
10

So che ci sono molte domande su questo argomento. Ho passato attraverso tutti loro ma niente sembra aiutare.Come ordinare la colonna DataGridView databound?

Come ordinare facendo clic sull'intestazione della colonna?

Come devo modificare questo codice per fare il lavoro?

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 
} 

risposta

14

Ricordo di aver problemi a trovare qualcosa che avrebbe funzionato quando ho aggiunto l'ordinamento ai miei DataGrids troppo. È possibile implementare un elenco bindable ordinabile aggiungendo prima la classe seguente al progetto. Si tratta di un'implementazione elenco che implementa BindingList<T>, in modo che sia possibile associare il datagrid ad esso e supporta anche l'ordinamento. Una migliore spiegazione dei dettagli di quanto avrei potuto dare è sulla 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; } 
} 

} 

Con questo in luogo, le uniche modifiche è necessario apportare al codice che avete pubblicato in precedenza è quello di creare un SortableBindingList basato sulla vostra lista e legarsi alla elenco ordinabile, piuttosto che quella standard, in questo modo:

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 

E che sarà sufficiente per farti andare.

+0

cool questo è !!! (+ 1A) –

4

Ecco il post del blog che mi ha veramente aiutato.

Presenting the SortableBindableList

Inoltre, controllare How do I implement automatic sorting of DataGridView? che ha esempi di questo e di un'altra libreria.

+1

+1 per il collegamento a un progetto completamente funzionale che implementa un SortableBindingList: è sufficiente inserire 2 file nel proprio progetto. Nota che l'autore ha aggiornato il codice un po 'su http://www.timvw.be/presenting-the-sortablebindinglistt-take-two/ - basta scaricare il file zip –

+1

Il primo link non è più valido ... – Grahamvs