mam klasę
class Person{
public string Name {get; set;}
public string Surname {get; set;}
}
i a List<Person>
do którego dodaję kilka pozycji. Lista jest powiązana z my 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;
Nie ma problemu. myGrid
wyświetla dwa wiersze, ale kiedy dodaję nowe pozycje do mojej persons
listy, myGrid
nie pokazuje nowej zaktualizowanej listy. Pokazuje tylko dwa wiersze, które dodałem wcześniej.
Więc jaki jest problem?
Rebindowanie za każdym razem działa dobrze. Ale kiedy wiążę a DataTable
z siatką, kiedy za każdym razem, gdy wprowadzam jakieś zmiany, DataTable
nie ma potrzeby ponownego wiązania myGrid
.
Jak rozwiązać ten problem bez ponownego wiązania za każdym razem?
One
sposób polega na użyciu BindingList, który wywoła zdarzenie, jeśli zmieni się lista bazowa. Innym sposobem jest użycieBindingSource
i wywołanie ResetBinding () za każdym razem, gdy dodajesz / usuwasz wiersz, ale to o wiele więcej pracy. Jeśli chcesz poinformować Grid o zmianach właściwości, najłatwiej to wdrożyćINotifyPropertyChanged
List<T>
. Ale jeśli programowo dodasz elementy do listy, DataGridView nie będzie o tym wiedział, ponieważ List nie zawiera implementuIBindingList
. Odnośnie BindingSource: często używam winforms i nie wiążę się z niczym innym niż BindingSource - FULLSTOP. Dodanie większej ilości szczegółów to zbyt wiele, aby dodać komentarz, aleBindingSource
ma tak wiele do zaoferowania bez żadnych wad.Anyone who does not use a BindingSource for binding has not fully understood windows forms databindings
BindingSource
jako pomost między źródłem danych a interfejsem użytkownika. Rozwiązuje wiele problemów związanych z wiązaniem danych. Chcesz ponownie załadować swoje dane? Po prostu ustawbindingSource.DataSource
nową kolekcję zamiast ponownego wiązania każdej kontrolki. Twoje źródło danych może mieć wartość NULL? ZestawbindingSource.DataSource = typeof(YourClass)
Chcesz mieć edytowalną siatkę, ale Twoje źródło danych nie ma konstruktora bez parametrów? Po prostu zaimplementujbindingSource.AddingNew
zdarzenie i stwórz obiekt samodzielnie. Nigdy nie doświadczyłem minusów podczas używania,BindingSource
ale wiele korzyści.Za każdym razem, gdy dodajesz nowy element do listy, musisz ponownie powiązać swoją siatkę. Coś jak:
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;
źródło
Tak, można to zrobić bez ponownego wiązania, implementując interfejs INotifyPropertyChanged.
Całkiem prosty przykład jest dostępny tutaj,
http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx
źródło
INotifyPropertyChanged
DataGridView, pokaże wszystkie zmiany właściwości, które mają miejsce w tle, ale nie będzie wiedział, czy dodasz / usuniesz wiersz ze źródła. Do tego celu służyIBindingList
interfejs i, dla Twojej wygody,BindingList<T>
implementacja, która już go implementuje, ale nie obsługuje sortowania / filtrowania.Po dodaniu nowej pozycji do
persons
dodania:myGrid.DataSource = null; myGrid.DataSource = persons;
źródło
null
jeśli od razu przypisujesz go dopersons
następnego wiersza?To nie jest dokładnie ten problem, który miałem, ale jeśli ktoś chce przekonwertować BindingList dowolnego typu na Listę tego samego typu, to jest to jak to zrobić:
var list = bindingList.ToDynamicList();
Ponadto, jeśli przypisujesz BindingLists typów dynamicznych do DataGridView.DataSource, upewnij się, że najpierw zadeklarowałeś go jako IBindingList, aby powyższe działało.
źródło