Обновление BindingSource в WinForms не обновляет сборку данных
Я хочу показать пользовательскую коллекцию в DataGridView
в приложении Windows Forms. Эта пользовательская коллекция реализует ICollection
и IEnumerable
. Я установил BindingSource
, используя коллекцию как свойство .DataSource. DataGridView
установлен для использования моего BindingSource
в качестве источника данных. Когда я добавляю новый элемент в коллекцию с помощью метода BindingSource.Add()
, DataGridView
корректно обновляется с новым элементом. С другой стороны, источник данных BindingSource
не имеет значения:
MyCustomCollection myCollection = new MyCustomCollection();
myCollection.Add(myCustomObject1);
myCollection.Add(myCustomObject2);
myBindingSource.DataSource(myCollection);
myBindingSource.Add(myCustomObject3);
В приведенном выше коде внутренний список myBindingSource содержит правильное количество записей (3), а DataGridView
также содержит три записи, но myCollection содержит только две записи. Я знаю, что изменение базового myCollection НЕ обновит BindingSource
или DataGridView
, так как это не BindingList<T>
, но я был под впечатлением, что обновление BindingSource
напрямую обеспечило бы, чтобы myCollection был обновлен на то же время.
Есть ли способ использовать коллекцию, которая не является BindingList<T>
, и обновлять ее при непосредственном взаимодействии с BindingSource
?
Обновить. Один из способов, которым я обновил данные во всех частях (Collection, BindingSource, DataGridView), выглядит следующим образом:
myCollection.Add(myCustomObject3);
myBindingSource.DataSource = null;
myBindingSource.DataSource = myCollection;
Я уверен, что есть лучший способ атаковать эту проблему, но это единственный метод, который породил результаты, которые я ожидал.
Ответы
Ответ 1
Проблема заключается в Fill Adapter. Когда вы загружаете форму, Заполнить выполняется для вас.
Просто убедитесь, что вы сделали Refill, а затем следите за Reset привязками, размещайте любые изменения данных, и Grid будет обновляться.
Пример:
WorkTableAdapter.Insert(objData.XAttribute, "",
objData.YAttribute,objLoanData.Amount_IsValid, DateTime.Now, DateTime.Now);
this.WorkTableAdapter.Fill(this.POCDataSet.Work);
this.WorkBindingSource.ResetBindings(false);
Ответ 2
Вам придется вручную вызвать ResetBindings() после изменения источника данных, если вы используете контейнер, который не может сделать это от вашего имени.
http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource.resetbindings.aspx
Вызывает управление, привязанное к BindingSource, чтобы перечитать все элементы в списке и обновить отображаемые значения.
Ответ 3
Сброс отдельного элемента работает!
Мне не повезло с .ResetBindings(false) и повторным назначением datsource, вызвавшим мерцание с накладными расходами potentiail, если только один элемент изменяется часто.
Я попробовал встроенный механизм с помощью PropertyChanged, но ничего не обновлялся.
Сброс отдельного элемента с использованием ResetItem()!
for (int i = 0; i < bindingSource1.Count; i++)
{
bindingSource1.ResetItem(i);
}
И даже лучше - если у вас есть событие обновления, связанное с каждым элементом данных в источнике bindningsource, вы можете найти объект в источнике привязки и использовать индекс объекта для вызова ResetItem (idx)
В этом случае мои пользовательские аргументы событий содержат ключ словаря к объекту данных, содержащемуся в отдельной коллекции. После того, как объект находится в использовании bindningsource.IndexOf(), он обновляется отдельно.
void Value_PropertyChanged(object sender, RegisterEventArgs e)
{
var idx = bindingSource1.IndexOf(registers_ref[e.registerID]);
if (idx>=0)
{
bindingSource1.ResetItem(idx);
}
}
Ответ 4
Я полагаю, что некоторое время назад я столкнулся с этой проблемой - я нашел в файлах свой код, и я думаю, что это решение, которое сработало для меня.
// Applies pending changes to the underlying data source.
this.bindingSource1.EndEdit();
Это было в контексте обработчика кликов для кнопки сохранения.