События EditingControlShowing запускаются несколько раз - PullRequest
1 голос
/ 24 февраля 2009

У меня есть DGV в VB.Net 2008, подключенный к таблице БД доступа. DGV не только для чтения, но полон столбцов только для чтения, кроме одного, который содержит поле со списком. Поле со списком позволяет пользователю выбрать результат для этой конкретной строки, а затем программа копирует предварительно рассчитанное значение в столбец «Прибыль» в зависимости от элемента, выбранного в выпадающем списке. Затем пользователь нажимает кнопку «Сохранить» и обновления БД (в настоящее время с помощью методов SQL в XSD).

Пока достаточно просто.

Вот код.

Private Sub DGUserBets_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DGUserBets.EditingControlShowing

    Dim combo As ComboBox = CType(e.Control, ComboBox)

    If (combo IsNot Nothing) Then

         // Remove an existing event-handler, if present, to avoid 
         // adding multiple handlers when the editing control is reused.
        RemoveHandler combo.SelectedIndexChanged, _
            New EventHandler(AddressOf DGUBStake_SelectedIndexChanged)

        // Add the event handler. 
        AddHandler combo.SelectedIndexChanged, _
            New EventHandler(AddressOf DGUBStake_SelectedIndexChanged)

    End If

End Sub


Private Sub DGUBStake_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)

    Dim myStatus As ComboBox = CType(sender, ComboBox)

    Dim row = DGUserBets.CurrentRow

    Select Case myStatus.SelectedIndex
        Case 0
            row.Cells("DGUBProfit").Value = 0
            // pending. no action
        Case 1
            row.Cells("DGUBProfit").Value = row.Cells("DGUBIfWin").Value
            // win
        Case 2
            // loses
            row.Cells("DGUBProfit").Value = row.Cells("DGUBIfLose").Value
        Case 3
            // void
            row.Cells("DGUBProfit").Value = 0
    End Select


End Sub

Проблема, с которой я столкнулся, заключается в том, что если пользователь выберет желаемый результат из комбинированного списка, но НЕ нажмет Enter, то просто подключится к другому комбинированному списку, чтобы снова выбрать результат для другой строки, первого обработчика событий. не отключается и, таким образом, события запускаются несколько раз. Затем это вызывает различные ошибки MsgBox по умолчанию и вызывает проблемы, когда пользователь пытается зафиксировать все изменения в программе DB / exit и т. Д. И т. Д.

Что мне нужно сделать? Нужно ли мне .EndEdit где-то уместно, чтобы заставить строку сохранить изменения? И где мне это назвать?

Спасибо.

Ответы [ 5 ]

2 голосов
/ 24 февраля 2009

У меня была похожая проблема, добавьте обработчик для CellLeave, если выходная ячейка - это ячейка, которую вы ищете (IE e.ColumnIndex = myEditableColumn.Index), затем вызовите gv.EndEdit ()

Также я бы порекомендовал сделать переменные-члены-обработчики для присваивания и удаления, потому что это выглядит лучше, чем всегда говорить «Удалить новое» и «Добавить новое».

2 голосов
/ 24 февраля 2009

Быстрый взгляд на код поднимает этот вопрос: Если вы создаете новый EventHandler при удалении существующего, это тот же самый?

0 голосов
/ 14 июня 2012

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

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

Private LastEventHandler As EventHandler = AddressOf Me.ComboBoxValueChanged

Private Sub dgvThisDatagrid_EditingControlShowing(sender As Object, e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles dgvOutstandingReminders.EditingControlShowing

    If TypeOf (e.Control) Is ComboBox Then
        Dim cboThisComboBox = DirectCast(e.Control, ComboBox)

        AddHandler cboThisComboBox.SelectedValueChanged, LastEventHandler

        AddHandler cboThisComboBox.Leave, AddressOf RemoveValueChangedHandler

    End If

End Sub

Private Sub ComboBoxValueChanged(ByVal sender As Object, ByVal e As System.EventArgs)

    If TypeOf (sender) Is ComboBox Then
        Dim cboThisComboBox = DirectCast(sender, ComboBox)

        MessageBox.Show("Value = " & cboThisComboBox.SelectedValue.ToString() & Environment.NewLine & "Text = " & cboThisComboBox.Text) ' Display index
    End If

End Sub

Private Sub RemoveValueChangedHandler(ByVal sender As Object, ByVal e As System.EventArgs)

    If TypeOf (sender) Is ComboBox Then
        Dim cboThisCombobox = DirectCast(sender, ComboBox)

        RemoveHandler cboThisCombobox.SelectedValueChanged, LastEventHandler
    End If

End Sub
0 голосов
/ 24 февраля 2009

Более простой код, который также, кажется, работает хорошо, как предложено CKRet:

    Dim combo As ComboBox = CType(e.Control, ComboBox)

    If (combo IsNot Nothing) Then

       RemoveHandler combo.SelectedIndexChanged, AddressOf DGUBStake_SelectedIndexChanged

       AddHandler combo.SelectedIndexChanged, AddressOf DGUBStake_SelectedIndexChanged

    End If
0 голосов
/ 24 февраля 2009

CKRet / Quintin, спасибо за быстрый ответ.

Быстрая попытка с этим кодом кажется лучше, а точка останова и пошаговое выполнение кода, похоже, корректно запускают события. Я довольно новичок в .NET, так как последнее настоящее программирование на VB, которое я делал, было VB6, поэтому я не уверен, что это самый элегантный способ решения проблемы.

Также обратите внимание, что когда LastEventHandler = Nothing, вызов RemoveHandler не выдает исключение, что весьма неплохо.

Может быть, я должен предложить MS, чтобы они обновили эту статью.

Private Sub DGUserBets_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DGUserBets.EditingControlShowing

    Dim combo As ComboBox = CType(e.Control, ComboBox)

    Static LastEventHandler As EventHandler

    If (combo IsNot Nothing) Then

        // Remove an existing event-handler, if present, to avoid 
        // adding multiple handlers when the editing control is reused.
        RemoveHandler combo.SelectedIndexChanged, _
            LastEventHandler

        LastEventHandler = New EventHandler(AddressOf DGUBStake_SelectedIndexChanged)

        // Add the event handler. 
        AddHandler combo.SelectedIndexChanged, _
            LastEventHandler

    End If


End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...