How to detect the change in a datagridviewcomboboxcolumn in a new datagridview row?

Posted on 2007-03-27
Last Modified: 2012-06-27
How to detect the change in a datagridviewcomboboxcolumn unbound column in a new row?  I have 2 datagridviews on a form.  The first grid has a several columns bound to a dataset with the addition of a datagridviewcomboboxcolumn inserted.  (Side note, even though I inserted it at column index 0 and it displays first in the grid, its actual index is 6 for some reason).  The datagridviewcomboboxcolumn is bound to a list of items in a datatable.  What I want to happen is when a user selects a new value in this column in a new row or changes a value in this column on an existing row for and event to fire.  In this event I need to add some rows orupdate some rows in datagridview2 based on the value in the datagridviewcomboboxcolumn.  I have been trying to use this approach:

    Private Sub DataGridView1_EditingControlShowing(ByVal sender As System.Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
        Dim cb As ComboBox = e.Control
        If Not cb Is Nothing Then
            ' first remove event handler to keep from attaching multiple:
            RemoveHandler cb.SelectedIndexChanged, AddressOf Me.editingComboBox_SelectedIndexChanged
            ' now attach the event handler
            AddHandler cb.SelectedIndexChanged, AddressOf Me.editingComboBox_SelectedIndexChanged

        End If
    End Sub
    Private Sub editingComboBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
    End Sub

The problem with this approach is this event gets fired for every row in the datagridview, not just the current row and then only after the focus has moved to a new "new row".  It does not fire on the actual change of the selection in the combocolumn.  I can't seem to find a list of the events in the order they happen when a user selects an item in a datagridviewcomboboxcolumn in a new row.
Question by:bjmanley
  • 2
  • 2
LVL 34

Expert Comment

ID: 18804697
I think you need to make two changes.  First, you will need to use the EditingControl's events to detect changes as they are actually made rather than waiting until the edit is "committed" by the user moving to another column or row.  Second, I think you may find it neater to turn the facility you want on and off other than by adding and removing handlers.  Try this.  At form level add a declaration on these lines

    Private WithEvents mycombo As System.Windows.Forms.DataGridViewComboBoxEditingControl

Having done that, if you click on mycombo (or whatever name you use) in the top lefthand dropdown in the code window, SelectedIndexChanged will be selectable in the righthand dropdown, and you can code into that.  My test code was this

    Private Sub mycombo_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles mycombo.SelectedIndexChanged
    End Sub

Then, in the

    Private Sub DataGridView1_EditingControlShowing(ByVal sender As System.Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing

change the code to something like this

        If TypeOf (e.Control) Is System.Windows.Forms.DataGridViewComboBoxEditingControl Then
            mycombo = e.Control
            If Not mycombo.DataSource Is Nothing Then 'SEE NOTE BELOW
                mycombo = Nothing
            End If
            mycombo = Nothing
        End If

The bit about the datasource is to restrict the "activation" of the SelectedIndexChanged code to the UNBOUND combobox column, as I'm not certain from your description whether you have some bound comboboxes in your datagridview as well.  If you don't, those three lines can go.

Although I've tested this, I must say that it's not something I've attempted before so I can't guarantee it's foolproof under real life conditions.  But, despite trying, I've not been able to break it so far.


Author Comment

ID: 18807660

This does seem to work a little better than what I was trying.  It is firing when I need it to on a new row but when I try to change the value in the combobox for an existing row it is still firing multiple times.  looks like this is what is happening:
empty datagrid
click on new row
choose first item in the combo (item index 0)
works great
now on the new "new row"
click on arrow of combobox
message that index is -1(current row)
message that index is 0 (previous row's index)
message that index is 0 (previous row's index)
then dropdownlist is displayed
I choose an item
message that index is equal to the item I chose.(current row)

It appears that the event fires for whatever the previous combobox was even if it was several rows apart.  very strange.  I am also trying a new approach and it works consistently but requires a commit of the row either by moving focus to another row or by the enter key.

    Private Sub DataGridView1_CellValueChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
        Dim mycell As DataGridViewCell = DataGridView1(e.ColumnIndex, e.RowIndex)
        Dim myname As String = mycell.OwningColumn.Name.ToUpper
        If mycell.OwningColumn.Name.ToUpper = "PARAGRAPH" Then
        End If
    End Sub

If you have any other ideas for an alternative approach let me know.  What this form is supposed to accomplish is to let the user choose from a list of paragraphs in the combobox in dgv1.  When they choose the paragraph, if it has some parameters that need values I build a list of them and display them in dgv2.  When printing, I roll through dgv1, get each paragraph in the order displayed in dgv1, populate it with the values for that paragraph in dgv2 which the user entered and so on until I have assembled a complete document.  I could probably go with some time of a chooser setup with 2 listboxes and arrows to move the selections back and forth and others to reorder the list but initially this seemed to take up less realestate and allowed the user to just change each row to the selection they wanted and no need for buttons to change the order of the items in the list, they could just change the combo on each row if they wanted a different order.  This app builds legal documents.
LVL 34

Accepted Solution

Sancler earned 500 total points
ID: 18808151
Where does the combo that we are concerned with get its Items collection from?  Your original post (which I've now re-read) referred to "a datagridviewcomboboxcolumn unbound column".  That's what I'd spotted and how I set up my test: i.e. by hardcoding some items into the combo.  But I now twig that it also said "datagridviewcomboboxcolumn is bound to a list of items in a datatable", so perhaps my test regime was wrong.

With the set-up I have I've not been able to reproduce the multiple firing to the extent you report.  I hadn't done a sequence like that you describe but when I've tried it now, I do get one "extra" report.  The "old" row I return to after a "new" row is reporting its existing selectedindex before I change that selection.  But I've overcome that with

    Private Sub myDataGridView_CellLeave(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles myDataGridView.CellLeave
        mycombo = Nothing
    End Sub

Can you try that, and see if it overcomes the problem?  If not, let me know the details of the binding set up and I'll have another think.


Author Comment

ID: 18808453
That appears to be it!  Great job! The combo is bound to another datatable.  There is one other column in dgv1 which is a button column and when selected it will display the full paragraph text in a popup for that paragraph key/brief description contained in the combo column using the DataGridView1_CellClick event and checking the column index .I have been struggling with this and I really appreciate your help on this as well as my previous question you worked on.  Too bad you didn't see my post on trying to make the text in the actual tab of a tab control page to display multiline/wordwrap instead of length question.  It went unanswered.  Thanks again!


Featured Post

Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
Variable Event ? 3 27
VB.Net Tranfer data between to VB.Net apps 8 25
Get number of Files in Directory and Sub Directories 2 41
It’s quite interesting for me as I worked with Excel using for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
This tutorial gives a high-level tour of the interface of Marketo (a marketing automation tool to help businesses track and engage prospective customers and drive them to purchase). You will see the main areas including Marketing Activities, Design …
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA.…

778 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question