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.
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.
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:
good luck!!!