Срабатывает System.NullRaferenceException при попытке изменить данные в Datagridview.ComboboxColumn
Проблема заключается в том, что повторное нажатие на comboboxcolumn приводит к возникновению исключения NullReferenceException в файле Program.cs на этапе Application.Run. Вводные данные следующие:
- имеется приложение Windows Form и на форме DatagridView, связанная с базой данных sql server;
- Одна из колонок DatagridView представляет из себя ComboboxColumn, но я работаю с ней как с обычным Combobox. Преобразование выполнила при помощи события EditingControlShowing, затем создала несколько событий уже для combobox:
private void dgrv1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
var cb = e.Control as DataGridViewComboBoxEditingControl;
cb.SelectedIndexChanged -= this.cb_SelectedIndexChanged;
cb.SelectedIndexChanged += this.cb_SelectedIndexChanged;
cb.DropDown -= this.cb_DropDown;
cb.DropDown += this.cb_DropDown;
cb.DropDownClosed -= this.cb_DropDownClosed;
cb.DropDownClosed += this.cb_DropDownClosed;
}
private void cb_DropDown(object sender, EventArgs e)
{
var cb = sender as DataGridViewComboBoxEditingControl;
string text = cb.text;
}
private void cb_SelectedIndexChanged(object sender, EventArgs e)
{
var cb = sender as DataGridViewComboBoxEditingControl;
int ind = cb.SelectedIndex;
dgrv1.CommitEdit(DataGridViewDataErrorContexts.Commit);
dgrv1.EndEdit;
}
private void cb_DropDownClosed(object sender, EventArgs e)
{
var cb = sender as DataGridViewComboBoxEditingControl;
dgrv1.EndEdit;
}
- Исключение возникает только при том условии, что срабатывает событие EditingControlShowing. Если его не включать, то все ОК, значит, проблема в нем. Ошибка возникает только при повторном нажатии на Comboboxcolumn, то есть при первом нажатии и выборе значения из выпадающего списка (либо при нажатии в любое другое место, то есть закрытии выпадающего списка без выбора) все события срабатываю корректно, а вот когда второй раз нажимаешь в той же строке или в любой другой на Comboboxcolumn - ошибка.
StackTrace
System.NullReferenceException
at System.Windows.Forms.DatatGridView.InitializeEditingControlValue(DataGridViewCellStyle& dataGridViewCellStyle, DatagridViewCell dataGridViewCell)
at System.Windows.Forms.DatatGridView.BeginEditInternal(Boolean selectAll)
at System.Windows.Forms.DatatGridView.BeginEdit(Boolean selectAll)
at System.Windows.Forms.DatatGridViewComboBoxCell.OnMouseClick(DataGridViewCellMouseEventArgs e)
at System.Windows.Forms.DatatGridView.OnMouseClick(DataGridViewCellMouseEventArgs e)
at System.Windows.Forms.DatatGridView.OnMouseClick(MouseEventArgs e)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.DataGridView.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int2 msg, IntPtr wparam, IntPtr Iparam)
at System.Windows.Forms.OnSafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnSafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopdata)
at System.Windows.Forms.Application.TreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.TreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at MyProject.Program.Main() in <путь к папке решения>\MyProject\Program.cs:line19
Ответы (2 шт):
Это потому что e.Control
не содержит тип DataGridViewComboBoxEditingControl
, поэтому cb = null.
Пропустить выполнение блока кода, если попался не тот тип, можно так:
private void dgrv1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is DataGridViewComboBoxEditingControl cb)
{
cb.SelectedIndexChanged -= this.cb_SelectedIndexChanged;
cb.SelectedIndexChanged += this.cb_SelectedIndexChanged;
cb.DropDown -= this.cb_DropDown;
cb.DropDown += this.cb_DropDown;
cb.DropDownClosed -= this.cb_DropDownClosed;
cb.DropDownClosed += this.cb_DropDownClosed;
}
}
Ну и вот это почитайте: Что такое NullReferenceException, и как мне исправить код?
Оказалось, что проблема в лишнем методе EndEdit в событии SelectedIndexChanged. Он там не нужен, т. к. завершение редактирования происходит по событию DropDownClosed, а если мы завершаем редактирование одной и той же ячейки два раза, то методы конфликтуют.