DataGridView NullReferenceException при InitializeEditingControlValue после потери фокуса - PullRequest
0 голосов
/ 12 августа 2011

У меня есть DataGridView, привязанный к списку [частей]. Последний элемент в списке всегда является «фиктивной частью», которая предназначена для создания дополнительной строки в сетке, чтобы пользователь мог начать ввод в первую ячейку, чтобы добавить часть в список. Как только пользователь вводит в эту конкретную ячейку более x символов, под ячейкой, в которой он печатает, появляется новый DataGridView с результатами поиска (немного посмотрим рекомендации Google), и он может выбрать одно из совпадений, чтобы добавить деталь к список.

Я делаю это, обрабатывая событие EditControlShowing, которое назначает «элемент управления для редактирования» переменной TextBox, которая имеет обработчик для TextChanged.

Ошибка:

Я хочу, чтобы фокус изменился на второй DataGridView (результаты поиска), если пользователь нажимает клавишу со стрелкой вниз. Обработчик EditControlShowing в первый раз работает нормально, перемещая фокус на второй DataGridView и оставляя первый DataGridView в «кажущемся» функциональном состоянии, то есть все другие обработчики событий работают. Но во второй раз, когда запускается обработчик EditControlShowing, DataGridView генерирует исключение NullReferenceException для InitializeEditingControlValue. Поскольку это собственный вызов DataGridView, который выдает ошибку, отладчик приводит меня к «Application.Run» в моем коде, который не помогает. Однако я определил, что вызов, который заставляет DataGridView перейти в это состояние, и точка, в которой генерируется исключение, - это когда я краду фокус из первого DataGridView, вызывая Focus () для второго DataGridView (или любого другого элемента управления для это важно). Однако если я позволю пользователю изменить фокус на DataGridView (например, щелкнув мышью), то DataGridView останется в порядке.

Кто-нибудь знает, почему кража фокуса от DataGridView во время обработчика для EditControlShowing должна привести к тому, что впоследствии он будет вести себя по-другому?

Я пробовал CancelEdit, Refresh, Enable / Disable и т.д ...

Любые предложения, которые помогут мне выяснить, что происходит в DataGridView? Я не могу обнаружить ничего очевидного, осматривая его на контрольных точках до и после. Я даже не знаю, как узнать, какой объект является нулевым, как его собственный код DataGridView ...

Большое спасибо.

1 Ответ

0 голосов
/ 17 августа 2011

ОК, я решил эту проблему, используя BeginInvoke в обработчике событий TextChanged (код написан на Boo, но должен иметь смысл):

//The event handler
private def CellAsTextBoxTextChanged(sender as object, e as EventArgs):
    ...
    self.BeginInvoke(ShowPartSelectionArea, currentCell, _CellAsTextBox.Text)

//The method which amongst other things, sets the focus to another control
private def ShowPartSelectionArea(currentCell as DataGridViewCell, searchString as string):
   ...
   AnotherDataGridView.Focus()
   ...

Ранее я пытался использовать BeginInvoke непосредственно в момент вызова Focus ()на другом элементе управления, например, так:

private def CellAsTextBoxTextChanged(sender as object, e as EventArgs):
    ...
    ShowPartSelectionArea(currentCell, _CellAsTextBox.Text)

private def ShowPartSelectionArea(currentCell as DataGridViewCell, searchString as string):
   ...
   self.BeginInvoke(AnotherDataGridView.Focus())
   ...

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

Так что для тех, кто сталкивается с той же проблемой, я бы посоветовал поиграть с тем, где в стеке вызовов вы используете BeginInvoke.

...