2013-05-22 17 views
57

Ho una classeLista Binding <T> di DataGridView in WinForm

class Person{ 
     public string Name {get; set;} 
     public string Surname {get; set;} 
} 

e un List<Person> a cui aggiungere alcuni elementi. L'elenco è associato al mio DataGridView.

List<Person> persons = new List<Person>(); 
persons.Add(new Person(){Name="Joe", Surname="Black"}); 
persons.Add(new Person(){Name="Misha", Surname="Kozlov"}); 
myGrid.DataSource = persons; 

Nessun problema. myGrid visualizza due righe, ma quando aggiungo nuovi elementi all'elenco persons, myGrid non mostra il nuovo elenco aggiornato. Mostra solo le due righe che ho aggiunto prima.

Quindi qual è il problema?

Il riavvolgimento ogni volta funziona bene. Ma quando lego un DataTable alla griglia ogni volta che apporto alcune modifiche a DataTable, non è necessario ReBind myGrid.

Come risolverlo senza ripetere ogni volta?

risposta

114

elenco non implementa IBindingList così la griglia non sa circa i vostri nuovi elementi.

Collegare invece DataGridView a BindingList<T>.

var list = new BindingList<Person>(persons); 
myGrid.DataSource = list; 

Ma vorrei anche andare oltre e legano la griglia a un BindingSource

var list = new List<Person>() 
{ 
    new Person { Name = "Joe", }, 
    new Person { Name = "Misha", }, 
}; 
var bindingList = new BindingList<Person>(list); 
var source = new BindingSource(bindingList, null); 
grid.DataSource = source; 
+0

Si dice che è possibile utilizzare IList e altre interfacce anche: http://msdn.microsoft.com/en-us/library/system .windows.forms.datagridview.datasource.aspx – Pacane

+1

@Pacane: Certo che puoi, ma DataGridView deve sapere se la tua origine dati ha delle modifiche. 'Uno' modo ist per utilizzare un BindingList, che genererà un evento se l'elenco sottostante cambia. Un altro modo è usare un 'BindingSource' e chiamare ResetBinding() ogni volta che si aggiunge/cancella una riga, ma questo è un modo per lavorare di più. Se si desidera informare la griglia sulle modifiche alle proprietà, il modo più semplice è implementare 'INotifyPropertyChanged' –

+4

perché si è utilizzato BindingList e BindingSource perché è possibile associare direttamente l'elenco alla proprietà dell'origine dati datagridview.discutere l'importanza di BindingList e BindingSource utilizzati qui. grazie – Mou

3

Ogni volta che aggiungi un nuovo elemento all'elenco, devi riagganciare la griglia. Qualcosa di simile:

List<Person> persons = new List<Person>(); 
persons.Add(new Person() { Name = "Joe", Surname = "Black" }); 
persons.Add(new Person() { Name = "Misha", Surname = "Kozlov" }); 
dataGridView1.DataSource = persons; 

// added a new item 
persons.Add(new Person() { Name = "John", Surname = "Doe" }); 
// bind to the updated source 
dataGridView1.DataSource = persons; 
+0

non riesco a vedere proprietà DataSource sotto datagrid.Can dirmi come posso usarlo? – RSB

1

Dopo aver aggiunto nuovo elemento alla persons aggiuntivo:

myGrid.DataSource = null; 
myGrid.DataSource = persons; 
+0

Non riesco a vedere la proprietà dataSource sotto datagrid. Puoi dirmi come lo uso? – RSB

+0

Questo suggerimento potrebbe causare problemi. Ad esempio, potresti scoprire che un clic su un elemento nella griglia potrebbe ottenere un _IndexOutOfRangeException_ poiché l'origine dati è nullo in quel punto. Sarebbe più saggio associare inizialmente a _BindingList_ e implementare _InotifyPropertyChanged_ sull'oggetto, mentre altre risposte indicano – steve

1

Sì, è possibile fare con rilegatura fuori implementando INotifyPropertyChanged Interface.

esempio molto semplice è disponibile qui,

http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx

+1

Ciò non è sufficiente, se si implementa 'INotifyPropertyChanged' il DataGridView mostrerà tutte le modifiche alle proprietà che si verificano in background, ma non saprà se si aggiunge/elimina una riga dalla sorgente. A tale scopo c'è un'interfaccia 'IBindingList' e, per la vostra convenienza, un 'BindingList ' di impiantazione che già lo implementa, ma non supporta l'ordinamento/filtraggio. –

+1

Sì, sarei d'accordo con te. quindi penso che ObservableCollection possa essere usato per questo. Cosa ne pensi? – Dev

Problemi correlati