2013-01-24 12 views
8

Ho uno DataGridView che è supportato da un SortableBindingListas described by this article.Mantenere un DataGridView autosortato

Questo è essenzialmente un BindingList cui origine dati è un elenco di oggetti personalizzati. Gli oggetti personalizzati sottostanti vengono aggiornati in modo programmatico.

Il mio SortableBindingList mi consente di ordinare ogni colonna in ordine crescente o decrescente. Ho fatto questo da sovraccaricare il metodo di ApplySortCore

protected override void ApplySortCore(PropertyDescriptor prop, 
             ListSortDirection direction) 

Questo metodo funziona bene per l'ordinamento quando l'intestazione di colonna viene cliccato, ma non sarà sorta automaticamente quando cella della colonna è programatically aggiornato.

Qualcun altro ha trovato una buona soluzione per mantenere un DataGridView ordinato da aggiornamenti programmatici della sua origine dati sottostante?

risposta

1

Considerate questa classe:

public class MyClass : INotifyPropertyChanged 
{ 
    private int _id; 
    private string _value; 

    public int Id 
    { 
     get 
     { 
      return _id; 
     } 
     set 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs("Id")); 
      _id = value; 
     } 
    } 
    public string Value 
    { 
     get 
     { 
      return _value; 
     } 
     set 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs("Value")); 
      _value = value; 
     } 
    } 
    public event PropertyChangedEventHandler PropertyChanged = new PropertyChangedEventHandler(OnPropertyChanged); 

    private static void OnPropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     // optional code logic 
    } 
} 

Aggiungi questi metodi per il vostro ordinabile elenco vincolante:

public class SortableBindingList<T> : BindingList<T>, INotifyPropertyChanged 
    where T : class 
{ 
    public void Add(INotifyPropertyChanged item) 
    { 
     item.PropertyChanged += item_PropertyChanged; 
     base.Add((T)item); 
    } 

    void item_PropertyChanged(object sender, PropertyChangedEventArgs e) 
    { 
     this.PropertyChanged(sender, new PropertyChangedEventArgs(String.Format("{0}:{1}", sender, e))); 
    } 

    // other content in the method body 
} 

e utilizzare questo metodo di esempio nella tua modulo:

public Form1() 
{ 
    InitializeComponent(); 
    source = new SortableBindingList<MyClass>(); 
    source.Add(new MyClass() { Id = 1, Value = "one test" }); 
    source.Add(new MyClass() { Id = 2, Value = "second test" }); 
    source.Add(new MyClass() { Id = 3, Value = "another test" }); 
    source.PropertyChanged += source_PropertyChanged; 
    dataGridView1.DataSource = source; 

} 

void source_PropertyChanged(object sender, PropertyChangedEventArgs e) 
{ 
    MessageBox.Show(e.PropertyName); 
    dataGridView1.DataSource = source; 
} 

private void button1_Click(object sender, EventArgs e) 
{ 
    ((MyClass)source[0]).Id++; 
} 
+1

grazie a questo funziona. Apprezzo l'aiuto! – chollida

4

Cercare di ignorare OnDataSourceChanged evento

public class MyGrid : DataGridView { 
    protected override void OnDataSourceChanged(EventArgs e) 
    { 
     base.OnDataSourceChanged(e); 
     MyComparer YourComparer = null; 
     this.Sort(YourComparer); 
    } 
} 
+0

grazie per l'aiuto. Avevo provato questo, ma non ha funzionato per avermi informato su tutte le modifiche programmatiche al DataSource sottostante – chollida