Безопасное обновление DataGridView / Dataset, когда DataGridView доступен для редактирования - PullRequest
1 голос
/ 14 марта 2011

У меня есть приложение WinForms, которое содержит набор данных ds и DataGridView dgv. dgv связан с ds.

ds обновляется с помощью Task (), которая периодически запрашивает базу данных, используя метод TableAdapter.Fill (). Здесь я сталкиваюсь с двумя проблемами.

  1. При обновлении ds dgv не обновляется, если только размер окна не изменен или другое событие не вызывает перерисовку формы.

  2. Когда пользователь начинает редактировать ячейку в dgv, ds обновляется и вызывает сбой пользовательского интерфейса из-за нескольких потоков, обращающихся к одному и тому же элементу управления GUI. Я попытался использовать флаг EditModeOn, который устанавливается определенными событиями из DataGridView dgv, хотя это не помогло предотвратить ошибки потока.

Каков наилучший способ иметь DataGridView, который может быть отредактирован пользователем и обновлен с помощью изменений в связанном наборе данных (который обновляется в другом потоке)?

Ответы [ 2 ]

2 голосов
/ 14 марта 2011

Для вашей точки # 2 вы можете использовать функцию Invoke из класса Control.Эта функция будет выполнять функцию в потоке пользовательского интерфейса.

http://msdn.microsoft.com/en-us/library/zyzhdc6b.aspx

Пример.:

// Invoke an anonymous method on the thread of the form.
this.Invoke((MethodInvoker) delegate
{
    //Call your function to update your datagridview with the dataset in parameters
    ...
});
1 голос
/ 14 марта 2011

В пункте # 1 вы можете исправить это, просто позвонив Form.Invalidate().Это заставит вашу форму перекрашиваться;это немного грязно, но это должно сработать.

В пункте №2, если у вас есть задача, которая обновляет содержимое элемента управления из другого потока, то вам следует всегда получитьисключение, так как доступ к элементу управления из любого потока, кроме потока пользовательского интерфейса, является недопустимым (поток, в котором он создан).Так что я не совсем понимаю, как вы это делаете.

Но я бы использовал поток, чтобы получить результаты, а затем сохранить их в переменной-члене (поле).Затем периодически проверяйте это поле, чтобы увидеть, нужно ли обновлять данные, и если взять данные из поля и поместить их в сетку, а затем обнулить поле.Вы можете использовать событие Tick класса System.Windows.Forms.Timer для реализации этой периодической проверки.

В своей процедуре обновления вы можете проверить свой флаг, чтобы увидеть, редактируется ли сеткаи игнорируйте обновления до позднего времени.

...