Для меня нормально работает следующее:
' ListChanged event is called whenever binding or datatable changes
Private Sub ProjectBindingSource_ListChanged(sender As Object, e As ListChangedEventArgs) Handles ProjectBindingSource.ListChanged
Select Case e.ListChangedType
' Only update when listchanges are of following types
Case ListChangedType.ItemChanged, ListChangedType.ItemAdded, ListChangedType.ItemDeleted
Try
'Update method will select the required update/insert/delete sql according to the tableadapter settings,
'after successful update, it will accept changes in the dataset and change status of all rows back to unchanged
Me.ProjectTableAdapter.Update(Me.StuklijstDataSet.Project)
Catch ex As Exception
' exceptions will bounce back from the server,
' this will handle all possible data problems: concurrency, foreign key constraints, null not allowed, ... ;
' the update method (see above) will also mark the row with an ErrorProvider icon and tooltip with the error message
' if update is unsuccessful, roll back changes to the datatable
Me.StuklijstDataSet.Project.RejectChanges()
' resetbindings to sort out problems with the control when rolling back adding or deleting records
Me.ProjectBindingSource.ResetBindings(False)
End Try
End Select
End Sub
Событие вызывается только 3-4 раза при загрузке данных, и проверка типа Listchanged очень быстрая (<1 мс).Существует свойство RaiseListChangedEvents объекта bindingsource, для которого можно установить значение False для временного поворота события ListChanged, но, похоже, это вызывает проблемы с заполнением таблицы данных.Я полагаю, что включать / выключать событие не обязательно. </p>
Сообщения об ошибках с сервера не очень удобны для пользователя.Описанный выше метод может быть расширен путем чтения исключения как объекта SqlException, получения кода ошибки SQL и изменения сообщения ErrorProvider в более простой текст.