У меня есть форма в моем приложении, которая отображает некоторые данные. Когда я впервые показываю форму, я загружаю некоторые данные в DataTable, а затем привязываю DataTable к DataGridView. Я также запускаю асинхронный метод, который выполняет несколько более медленных запросов к базе данных. Когда эти медленные запросы полный, мне нужно обновить несколько сотен строк в DataTable, заполнения значений, возвращаемых из медленных запросов, например, так:оптимизировать обновления DataTable, привязанные к DataGridView
foreach (DataRow row in data.Rows)
{
SlowLoadingData slow_stuff = slow_query_results[(int)row["id"]];
row.BeginEdit();
row[column_one] = slow_stuff.One;
row[column_two] = slow_stuff.Two;
row[column_three] = slow_stuff.Three;
row.EndEdit();
}
Это крайне медленно, висит потока пользовательского интерфейса в течение минуты или больше, по-видимому, потому, что каждая строка вызывает перерисовку.
После некоторого исследования я нашел способ сделать это быстро. Во-первых, привяжите DataGridView к BindingSource, который привязан к DataTable, а не непосредственно к DataTable. Затем выполните следующие действия, когда вы внести изменения в DataTable:
binding_source.SuspendBinding();
binding_source.RaiseListChangedEvents = false;
// foreach (DataRow in Data.Rows) ... code above
binding_source.RaiseListChangedEvents = true;
binding_source.ResumeBinding();
grid.Refresh();
Существует проблема, хотя, и это Doozy: код выше предотвращает DataGridView от обнаружения новых строк добавлены в DataTable. Любые новые строки, добавленные в таблицу, не отображаются в сетке. Сетка также может генерировать исключения, если вы используете клавиши со стрелками для перемещения текущего выбора ячейки с нижнего конца сетки, поскольку у базового источника данных больше строк, но сетка не создала строки сетки для их отображения.
Таким образом, возможны два решения, которые я могу видеть:
Есть ли лучший способ для подавления обновления привязки во время внесения изменений в базовой DataTable?
Есть ли простой способ сообщить DataGridView изящно обновить коллекцию строк сетки в соответствии с количеством базовых строк DataTable? (Примечание: Я пытался дозвониться BindingSource.ResetBindings, но это, кажется, вызывает больше исключений, если у вас есть удалены строк из DataTable)
Я не знаю много об использовании источника привязки, но делает ли возобновление привязки перед установкой raiselistchangedevents в true, чтобы какая-либо разница? – eglasius
Я пробовал все возможные порядки вызова методов. Все, что требуется для сетки, чтобы прикрутить, это то, что RaiseListChangedEvents является ложным при добавлении новой строки. –
Вызов функции ResetBindings для принудительного обновления пользовательского интерфейса. – CodingBarfield