У меня есть класс
class Person{
public string Name {get; set;}
public string Surname {get; set;}
}
и, List<Person>
к которому я добавляю некоторые элементы. Список привязан к моему 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;
Нет проблем. myGrid
отображает две строки, но когда я добавляю новые элементы в свой persons
список, myGrid
новый обновленный список не отображается. Он показывает только две строки, которые я добавил ранее.
Так в чем проблема?
Переплет каждый раз работает хорошо. Но когда я привязываю DataTable
к сетке, когда каждый раз, когда я DataTable
вношу какие- то изменения , нет необходимости в повторной привязке myGrid
.
Как решить без перепривязки каждый раз?
One
способ использовать BindingList, который вызовет событие, если базовый список изменится. Другой способ - использоватьBindingSource
и вызывать ResetBinding () каждый раз, когда вы добавляете / удаляете строку, но это намного больше работы. Если вы хотите информировать Grid об изменениях свойств, самый простой способ - это реализоватьINotifyPropertyChanged
List<T>
если хотите. Но если вы программно добавляете элементы в список, DataGridView не будет знать об этом, потому что список не реализуетIBindingList
. Что касается BindingSource: я много использую winforms и не привязываюсь ни к чему другому, кроме BindingSource - FULLSTOP. Добавлять больше деталей - это слишком сложно для комментария, ноBindingSource
есть что предложить без каких-либо недостатков. Я бы пошел так далеко и сказалAnyone who does not use a BindingSource for binding has not fully understood windows forms databindings
BindingSource
как мост между вашим источником данных и вашим графическим интерфейсом. Он решает многие проблемы, связанные с привязкой данных. Вы хотите перезагрузить данные? Просто установитеbindingSource.DataSource
свою новую коллекцию вместо того, чтобы повторно связывать каждый элемент управления. Ваш DataSource может быть нулевым? УстановитьbindingSource.DataSource = typeof(YourClass)
Вы хотите иметь редактируемую сетку, но в вашем источнике данных нет конструктора без параметров? Просто реализуйтеbindingSource.AddingNew
событие и создайте объект самостоятельно. У меня никогда не было недостатков при использовании,BindingSource
но было много преимуществ.Каждый раз, когда вы добавляете новый элемент в список, вам необходимо повторно привязать свою сетку. Что-то типа:
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;
источник
Да, можно обойтись без повторной привязки, реализовав интерфейс INotifyPropertyChanged.
Довольно простой пример доступен здесь,
http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx
источник
INotifyPropertyChanged
DataGridView, он будет отображать все изменения свойств, которые происходят в фоновом режиме, но он не будет знать, добавляете ли вы / удаляете строку из своего источника. Для этого естьIBindingList
интерфейс и, для вашего удобства,BindingList<T>
имплементация, которая уже реализует его, но не поддерживает сортировку / фильтрацию.После добавления нового элемента
persons
добавить:myGrid.DataSource = null; myGrid.DataSource = persons;
источник
null
если сразуpersons
на следующей строке назначать ?Это не совсем та проблема, с которой я столкнулся, но если кто-то хочет преобразовать BindingList любого типа в список того же типа, то вот как это делается:
var list = bindingList.ToDynamicList();
Кроме того, если вы назначаете BindingLists динамических типов DataGridView.DataSource, убедитесь, что вы сначала объявили его как IBindingList, чтобы все вышеперечисленное работало.
источник