DataGridView & ComboBox Event? - vb.net

Using VB.Net, I have a DataGridView with a ComboBox Column. What even do I use for when the user changes a selection in the ComboBox?

you can this event when the combobox value has been selected ...
Private Sub dataGridView_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs)
Try
If (Me.dataGridView.CurrentCell.ColumnIndex = CType(Column.Col,Integer)) Then
Dim comboBox As ComboBox = CType(e.Control,ComboBox)
If (Not (comboBox) Is Nothing) Then
AddHandler comboBox.SelectedIndexChanged, AddressOf Me.ComboBoxIndexChanged
End If
End If
Return
Catch Ex As Exception
Utils.ErrMsg(Ex.Message)
Return
End Try
End Sub

SelectedValueChanged

.FormatedValue as in Grid.Item.FormatedValue instead of Value

CurrentCellDirtyStateChanged - then test for the current cell being in your column of concern.

Related

how i can create selected_index_changed event of combobox in datagridview

my datagridview name is "DG" and i add combobox column programatically named item as shown in code below.i want to create the event which call on itemchanged of combobox.i use DG_CellLeave event but it not call after the item selection immediatly but call when we leave the cell.i want to create event which immediatly call on selection change event of combobox.
Dim item As New DataGridViewComboBoxColumn
item.DataSource = dset.Tables("tab")
item.HeaderText = "item"
item.Name = "item"
item.DisplayMember = "p_name"
item.DataPropertyName = "item"
DG.Columns.Add(item)
which event should i choose for this purpose...
You should take a look at: DataGridView.EditingControlShowing Event. This event is raised whenever an edit control is shown in the DataGridView. It can be handled/used like below:
Dim gridComboBox As ComboBox
Private Sub DG_EditControlShowing(sender As Object, e As DataGridViewEditingControlShowingEventArgs)
' Check to see if the ColumnIndex is where we expect to have the DropDown
If (DG.CurrentCell.ColumnIndex = 1) Then
' Get the ComboBox that is being shown
gridComboBox = TryCast(e.Control, ComboBox)
If Not (gridComboBox Is Nothing) Then
' Always remove the Event Handler before Adding, when setting them at runtime
RemoveHandler gridComboBox.SelectedIndexChanged, AddressOf gridComboBox_SelectedIndexChanged
AddHandler gridComboBox.SelectedIndexChanged, AddressOf gridComboBox_SelectedIndexChanged
End If
End If
End Sub
Private Sub gridComboBox_SelectedIndexChanged(sender As Object, e As EventArgs)
Dim dropDown As ComboBox = TryCast(sender, ComboBox)
if not(dropDown is nothing) then
Dim drv as DataRowView = dropDown.SelectedItem
if Not (drv is nothing) then
Debug.Print(drv("item"))
end if
end if
End Sub
The SelectedIndexChanged event is raised as per a ComboBox used outside of a DataGridView.

VB.Net Datagridview combobox add a handler

I've spent a day trying to figure out how to solve my problem, which is identical to
this related unanswered question
On the first combobox, my code works fine, no problem. When I try to change the combobox it throws an error Null Reference Exception
This is my code:
Private Sub dgvSurveyQuestions_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles dgvSurveyQuestions.EditingControlShowing
Dim editingComboBox As ComboBox = TryCast(e.Control, ComboBox)
If Not editingComboBox Is Nothing Then
'Add the handle to your IndexChanged Event
RemoveHandler editingComboBox.SelectedIndexChanged, AddressOf editingComboBox_SelectedIndexChanged
AddHandler editingComboBox.SelectedIndexChanged, AddressOf editingComboBox_SelectedIndexChanged
End If
'Prevent this event from firing twice, as is normally the case.
'RemoveHandler dgvSurveyQuestions.EditingControlShowing, AddressOf dgvSurveyQuestions_EditingControlShowing
End Sub
Private Sub editingComboBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Dim editingComboBox As ComboBox = TryCast(sender, ComboBox)
If editingComboBox Is Nothing Then Exit Sub
'Show your Message Boxes
MessageBox.Show(editingComboBox.SelectedValue.ToString) ' throws error here
End Sub
I'm still working on a different workaround, like adding a handler while the datagridview is populated or whatever.. I don't even know if this is possible but I need to do this.
I'm really stuck here, can someone shed some light and advice me on what to do? Thanks
Simply check if editingComboBox.SelectedValue is Nothing.
The DataGridView reuses only one ComboBox instance, and internally resets the DataSource of the ComboBox when the user selects another ComboBox cell.
Then the event SelectedIndexChanged raises and SelectedValue will be Nothing at that time.

Datagridview comboBox not selecting on click/edit

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.
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!!!
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.

Vb.net / DataGridView / ComboBox Column

I am using vb.net and winforms.
I have a Form with a Bound DataGridView. On the DGV I have 5 columns with ComboBox. I am using the EditingControlShowing Even to catch the ComboBox Selection. (see code bellow).
Here is the problem:
After I click on a Cell with a ComboBox and make a Selection and then update the underlying cell (cell = selected value) and then click on another Row of the DGV it goes haywire. If after I update the Cell I do and EndEdit on the corresponding row of the DataSource it seems to work find.
How can I determine whe corresponding Data Source row so that I can automate this?
Private Sub dataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As DataGridViewEditingControlShowingEventArgs) _
Handles DataGridView1.EditingControlShowing
Try
Debug.Print("entered the EditingControlShowing")
Dim ColName As String = Me.DataGridView1.Columns(Me.DataGridView1.CurrentCell.ColumnIndex).Name
If ColName = "Col1" Then 'Or ColName = "Col2" Or ColName = "Col3" Or ColName = "Col4" Or ColName = "Col5" Then
'the column you want to cast
Dim cmb As ComboBox = TryCast(e.Control, ComboBox)
RemoveHandler cmb.SelectedIndexChanged, AddressOf cmb_SelectedIndexChanged
AddHandler cmb.SelectedIndexChanged, AddressOf cmb_SelectedIndexChanged
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Sub cmb_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
Try
Me.DataGridView1.Rows(Me.DataGridView1.CurrentRow.Index).Cells(Me.DataGridView1.CurrentCell.ColumnIndex).Value = CType(sender, ComboBox).SelectedItem
'
' HERE IF I PUT MyDataSet.Tables(0).Rows(?).EndEding it works - but how to konw what row?
'
UpdateAvgColumn(Me.DataGridView1.CurrentRow.Index)
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
The events being fired are reentering. If you are currently processing an event, you have to be careful not to process other events. You have to put IF statements around the processing of the events to skip executing the code, if a different event is being processed.
sub dgv_selecteditemchanged()
If not processing_event
processing_event = true
...
processing_event = false
end if
end sub

EditingControlShowing events firing multiple times

I have a DGV in VB.Net 2008 connected to an Access DB table. The DGV is not Read Only, but is full of read-only columns except for one, which contains a combo box. The combo box allows the user to select an outcome for that particular row, and then the program copies in a pre calculated value into the "Profit" column depending upon the item selected in the combobox. Then the user hits the Save button and the DB updates (currently via SQL methods in the XSD).
Easy enough so far.
Here is the code.
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
The problem I have is that it would seem that if a user selects the desired outcome from the combobox but does NOT hit Enter, and simply mouses on to a different combobox to again select the outcome for a different row, the first eventhandler is not disconnected and thus the events fire multiple times. This then causes various default MsgBox errors and brings up problems when the user tries to commit all changes to the DB/exit program etc etc.
What do I need to do? Do I need to .EndEdit somewhere appropriate to force the row to save the changes? And where should I call this?
Thank you.
A quick glance at the code brings up this question:
If you create a new EventHandler when removing the existing one is it the same one?
I have had a similar issue, add a handler for CellLeave if the cell being exited is the cell you are looking for (IE e.ColumnIndex = myEditableColumn.Index) then call gv.EndEdit()
Also I would recommend making the handlers member variables for assignment and removal because it seems nicer then always saying Remove New and Add New.
CKRet/Quintin , thank you for the fast responses.
A quick try with this code seems better and breakpointing and stepping through the code seems to be firing the events correctly. I'm fairly new to .NET as the last real VB programming I did was VB6 so I'm not sure if this is the most elegant way to solve the problem.
Also a note that when LastEventHandler = Nothing, calling the RemoveHandler does not throw an exception, which is quite nice.
Maybe I should suggest to MS they should update that article.
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
Simpler code which also appears to work well, as suggested by 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
I know this is an archaic post, but after buggering around with this same problem for half a day I've found a way to solve this another way, so I thought it would be worth sharing.
Adding a second handler to handle the leave event of the combobox which then removes the handler of selectedvalue changed. Appears to work quite slick, and unlike another option i found gives the desired resulting action (unlike removing the value changed handler on the actual handling event which then won't fire if you re-select from the same combobox)
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