Datagridview comboBox not selecting on click/edit

2019-09-02 10:48发布

问题:

I have a datagridview which has a combox column that contains two values. When a row's combobox value has been changed I'm updating the backend database with the change.

The core problem is the data only changes after you click on the drop down arrow, and select the record. If you click on the combobox cell itself and select the value it doesn't do anything because the combobox selected item is empty.

What's confusing me is this works correctly within Visual Studio apart from the initial click following this it works fine, but when the application is ran directly the combobox runs slow, it takes 2 to 4 clicks of the combo box to actually detect that the value has changed.

This is the editcontrol handler.

 Private Sub DataGridView_Changer(sender As Object, e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) _
    Handles DataGridView.EditingControlShowing
    Try
        Dim Combo As ComboBox = CType(e.Control, ComboBox)
        If Not IsNothing(Combo.SelectedItem) Then
            RemoveHandler Combo.SelectedIndexChanged, New EventHandler(AddressOf ComboHandler)
            AddHandler Combo.SelectedIndexChanged, New EventHandler(AddressOf ComboHandler)
        End If
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub

This is the combobox handler where the data change occurs and updates the DB

    Private Sub ComboHandler(sender As Object, e As EventArgs)
            Try
                Dim EmailID As Integer = DataGridView.CurrentRow.Cells("EmailID").Value
                Dim Sent As Boolean = DataGridView.CurrentRow.Cells("BeenSent").Value
                If Sent = True Then
                    Exit Sub
                End If
                Dim EMRec As DBClass.EmailRecordDB = EmailArchive.Where(Function(X) X.EmailID = EmailID).FirstOrDefault
                Dim Combo As ComboBox = CType(sender, ComboBox)
                If Combo.SelectedItem.ToString = "Failed" Then
                    EMRec.SentAttempt = 999
                    EMRec.BeenSent = False
                ElseIf Combo.SelectedItem.ToString = "Resend" Then
                    EMRec.SentAttempt = 0
                    EMRec.BeenSent = False
                End If
                EMRec.ResetStatus() 'DB Update 
                DirtyCell()
                Exit Sub
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try
        End Sub
Sub DirtyCell() 'Handles DataGridView.CurrentCellDirtyStateChanged
    If DataGridView.IsCurrentCellDirty Then
        Try
            DataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit)
                     ContextualSearch() ' Refresh Grid
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

    End If
End Sub

UPDATE 24/04/2014

I've tweaked DirtyCell() and removed the if statement, so it commits the change regardless of if the cell is dirty or not. This seems to have made a bit of an improvement.

  Sub DirtyCell() 'Handles DataGridView.CurrentCellDirtyStateChanged
            Try
                DataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit)
                         ContextualSearch() ' Refresh Grid
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try      
    End Sub

UPDATE 25/04/2014

I've still got an issue with the combobox cell being initially selected. It still requires 3+ clicks for the value change to actually take effect and trigger the combohandler event.

I am at a loss as to how to resolve this.

回答1:

ok here is what i figured. the selectedIndexChanged does not work properly in many cases like yours, and mine sometimes. i prefer SelectionChangeCommited. Another issue is with your AddHandler and removeHandler. You should Store your selected combo in a global varable and then remove event handler when your start editing the next combo. see the suggested code below. it is working here for me :)

Edit like below in DataGridView_Changer:

Private lastCombo As ComboBox  ''global variable to remember last combo with eventHandler i
Private Sub DataGridView_Changer(sender As Object, e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) _
Handles DataGridView.EditingControlShowing
 Try
    Dim Combo As ComboBox = CType(e.Control, ComboBox)
    If Not IsNothing(Combo.SelectedItem) Then
        If Not IsNothing(lastCombo) Then
                RemoveHandler lastCombo.SelectionChangeCommitted, New EventHandler(AddressOf ComboHandler)
       End If
       lastCombo = Combo   
       AddHandler lastCombo.SelectionChangeCommitted, New EventHandler(AddressOf ComboHandler)
    End If
 Catch ex As Exception
    MsgBox(ex.Message)
 End Try
End Sub

good luck!!!



回答2:

Instead of trapping and attempting to do an update while the edit event was occurring (hindsight) I used the CellValueChanged event.

The Combobox field contains 2 values but by default the value of the cell was empty.

When CellValueChanged is triggered it's after the cell's value has been updated.

I'd added CurrentCellDirtyStateChanged to DirtyCell to automatically commit the data change and rerun the query.

Such a simple change as using CellvalueChanged fixed the issue.