none
Исключение во время обработки EditingControlShowing RRS feed

  • Общие обсуждения

  • У меня на форме есть DataGridView и в нем есть два столбца типа ComboBox. Содержимое второго столбца зависит от содержимого первого столбца. Для простоты пусть будет, что в первом столбце можно выбрать из двух значений - "Буквы" и "Цифры". И содержимое второго столбца должно меняться в соответствии с выбранным значением первого столбца. Все работает хорошо, только вот появилась необходимость менять содержимое второго столбца не после завершения редактирования ячейки, а сразу после выбора другого значения. Это можно реализовать с помощью события DataGridView.EditingControlShowing, в котором я получаю компонент списка и подписываюсь на событие изменения его индекса (SelectedIndexChanged). Это тоже работает хорошо. НО если в одной из ячеек типа ComboBox я открою список и не буду ничего выбирать, а сразу кликну на другую ячейку с списком, то при попытке открыть ее список, я получаю исключение:

    Сам код:

    private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) { if (e.Control is DataGridViewComboBoxEditingControl) { cbControl = (DataGridViewComboBoxEditingControl)e.Control; cbControl.SelectedIndexChanged -= new EventHandler(comboBox_SelectedIndexChanged); cbControl.SelectedIndexChanged += new EventHandler(comboBox_SelectedIndexChanged); } } private void comboBox_SelectedIndexChanged(object sender, EventArgs e) { if (cbControl != null) { dataGridView1.EndEdit(); cbControl.SelectedIndexChanged -= new EventHandler(comboBox_SelectedIndexChanged); } }


    26 августа 2020 г. 15:29

Все ответы

  • Смотрите детали исключения, там будет строка где оно произошло. 

    Скорее всего ошибка в коде ниже где вы убирайте обработчик который может быть и не установлен. 

    cbControl.SelectedIndexChanged -= new EventHandler(comboBox_SelectedIndexChanged); cbControl.SelectedIndexChanged += new EventHandler(comboBox_SelectedIndexChanged);


    This posting is provided "AS IS" with no warranties, and confers no rights.

    26 августа 2020 г. 18:43
    Модератор
  • Так в том-то и дело, что он показывает строку, в которой вызывается форма, в другом классе. Этой ошибки нет, только если убрать подписывание на событие, а оно тут необходимо.
    26 августа 2020 г. 19:16
  • Смотрите на stack trace на исключении, включите останов на исключениях или поставьте точку остановки на вашем коде.

    Наверное не повредит прочитать вот это:

    https://docs.microsoft.com/ru-ru/visualstudio/debugger/debugging-absolute-beginners?view=vs-2017


    This posting is provided "AS IS" with no warranties, and confers no rights.

    26 августа 2020 г. 20:36
    Модератор
  • Разумеется я уже просмотрел StackTrace. Вот его полное содержимое:

    System.Windows.Forms.DataGridView.InitializeEditingControlValue(DataGridViewCellStyle& dataGridViewCellStyle, DataGridViewCell dataGridViewCell)
    System.Windows.Forms.DataGridView.BeginEditInternal(Boolean selectAll)
    System.Windows.Forms.DataGridView.BeginEdit(Boolean selectAll)
    System.Windows.Forms.DataGridViewComboBoxCell.OnMouseClick(DataGridViewCellMouseEventArgs e)
    System.Windows.Forms.DataGridView.OnCellMouseClick(DataGridViewCellMouseEventArgs e)
    System.Windows.Forms.DataGridView.OnMouseClick(MouseEventArgs e)
    System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
    System.Windows.Forms.Control.WndProc(Message& m)
    System.Windows.Forms.DataGridView.WndProc(Message& m)
    System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
    System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
    System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
    System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
    System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
    System.Windows.Forms.Application.Run(Form mainForm)
    test_dgvcb.Program.Main() в D:\\OneDrive\\Visual Studio Projects\\test_dgvcb\\test_dgvcb\\Program.cs:строка 19

    Ни одно событие, которые упоминаются, у меня не используются.

    Я не знаю, где мне ставить точку остановки - если я убираю событие comboBox_SelectedIndexChanged, то этой ошибки нет, но если это событие остается, то во время отладки оно не срабатывает - сразу исключение в другом классе.  

    26 августа 2020 г. 20:49
  • Что то вы сделали что привело к исключению в стороннем коде. Исходники тут:

    https://referencesource.microsoft.com/#System.Windows.Forms/winforms/Managed/System/WinForms/DataGridViewMethods.cs,1f08bf597a7900e1

    Так же можете включить отладку кода .Net (с поддержкой сервера символов и исходники) чтоб понять проблему.

    Однако я вам скажу что ваш код который отключает обработчик и сразу же его подключает мне не нравится. 


    This posting is provided "AS IS" with no warranties, and confers no rights.

    26 августа 2020 г. 22:16
    Модератор
  • Однако я вам скажу что ваш код который отключает обработчик и сразу же его подключает мне не нравится. 

    Я так учился - отключать не подключенный обработчик не страшно, страшно подключать уже подключенный обработчик событий. Поэтому я сперва пробую отключать обработчик, на тот случай, если он уже был где-то подключен.


    26 августа 2020 г. 22:23
  • Однако я вам скажу что ваш код который отключает обработчик и сразу же его подключает мне не нравится. 

    Я так учился - отключать не подключенный обработчик не страшно, страшно подключать уже подключенный обработчик событий. Поэтому я сперва пробую отключать обработчик, на тот случай, если он уже был где-то подключен.


    Не припомню чтоб я где то видел такой подход. Для начала, он явно не оптимален.

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

    В любом случае краш явно следствие манипуляций с обработчиком. Может быть дело в самом обработчике. 


    This posting is provided "AS IS" with no warranties, and confers no rights.

    26 августа 2020 г. 22:54
    Модератор
  • В любом случае краш явно следствие манипуляций с обработчиком. Может быть дело в самом обработчике.

    Полностью согласен! Я нашел способ избавиться от этой ошибки, но тогда ячейки таблицы начинают вести себя не так как ожидается. Так что я все еще ищу решение. 
    26 августа 2020 г. 23:01