DataGridViewComboBoxColumn Selection Changed
-
Wednesday, July 06, 2005 6:22 AMHi,
I would like to handle the Selection Changed event of a ComboBox column inside my datagrid, what would be the best method to do it. I tried the CellValueChanged event but that throws up an error when I am loading the datagrid. Please suggest how to do this.
Thanks,
Kunal
All Replies
-
Wednesday, July 06, 2005 11:48 PMYou need to handle the EditingControlShowing event on the DataGridView control and cast the editing control to a ComboBox. Then you can hook up the SelectionChanged event like normal.
-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is" -
Thursday, July 07, 2005 3:59 AMHi Mark,
The editing control is itself a ComboBox, so why should I recast it? Also, can you please give the code of how to hook up the SelectedChange event if I recast it?
Thanks,
Kunal -
Friday, July 08, 2005 12:35 AM
In VB you don't need to recast it (unless you have option strict enabled). In C# you do. Here is the VB code:
Private Sub DataGridView1_EditingControlShowing(ByVal sender As System.Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
Dim editingComboBox As ComboBox = e.Control
AddHandler editingComboBox.SelectedIndexChanged, AddressOf Me.editingComboBox_SelectedIndexChanged
End Sub
Private Sub editingComboBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
End Sub
-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is" -
Friday, July 08, 2005 3:20 AM
Hi Mark,
I did what you told and in the event handler I just wrote a code for
MessageBox.Show(CType(sender, ComboBox).SelectedIndex)
Now this is what is happening.
I click on the ComboBox column in the first row and change its value. and go to the next cell. The event does not get fired.
Now I click on the same ComboBox again, and the MessageBox comes up twice.
Then I click on the same ComboBox again, and the MessageBox comes up thrice.
And so on. Thus the problem is two fold, the event handler is not called when the Index changes and secondly, it is called multiple times. Multiple times could be because the event handler is added every time, but why isnt it getting called when the index actually changes is something I couldnt find out.Even if I click on some other rows ComboBox column the same behaviour is repeated. Please suggest a way out, and also why is it not getting called when the index actually changes. I am using the Dec 2004 CTP build
Thanks,
Kunal
[Edit] I modified the EditingControlShowing event as below. But now also the handler is getting called twice.
Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
Dim editingComboBox As ComboBox = e.Control
Try
RemoveHandler editingComboBox.SelectedIndexChanged, AddressOf Me.editingComboBox_SelectedIndexChanged
Catch ex As Exception
MessageBox.Show("Exception")
End TryAddHandler editingComboBox.SelectedIndexChanged, AddressOf Me.editingComboBox_SelectedIndexChanged
End Sub -
Friday, July 08, 2005 5:44 AMyes - this is the result of the editing control being reused and the fact that the combobox is databound. the SelectionChangeCommitted event might be a better event for what you are trying to do.
In newer builds this is the order when I get the messagebox for the SelectedIndexChanged event:
1) I click on the ComboBox column in the first row and change its value -- I get the messagebox.
2) when I goto the next cell I do not get the message.
3) When I click on the same combobox again I do not get the message.
4) If I select a different value in the same combobox I get the message
5) If I select a different combobox on a different row I get 3 messageboxes: These are due to the cell's value being committed.
I'm going to investigate if there is something we can do for this. Thanks for the feedback!
-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is" -
Friday, July 08, 2005 5:54 AM
Thanks for the reply Mark, I think SelectionChangeCommitted should work for me once I get the Beta 2. In Beta 1 it isnt getting fired properly. -
Monday, October 24, 2005 11:01 AM
Hey Mark,
To get rid of this problem(getting messages again again!) I made one private variable of type combo box and make sure that the event register only one time. Now the message I am getting is only one time.
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
//This is private variable ComBoBox.
if (combo == null){
combo = (
ComboBox)e.Control;combo.SelectedIndexChanged +=
new EventHandler(combo_SelectedIndexChanged);}
}
private void combo_SelectedIndexChanged(object sender, EventArgs e){
MessageBox.Show("Coming");}
-
Wednesday, November 15, 2006 5:37 PM
HI Mark.
I am working on same. And I get the same error. Do you get any solution now? Please response me.
Thanks,
Sachin -
Wednesday, November 15, 2006 10:02 PM
Hi,
Do you get the solution for this..I am also facing the same problem.. But I don't know how to resolve this..
Please send me sample code..
-
Friday, November 24, 2006 2:22 PM
Hi
I think Mark has already pointed out that you should use SelectionChangeCommitted event because it insures that user has finished with the item which he wants to selects.
The annoying thing that the message is coming again and again; It is happening because EditingControlShowing event fires every time when you reach to the next row and you dare to edit the cell containing that control (combo box in this case). In order to prevent the message box from coming again and again you should first "Un-Wire" the event and then "Wire" the event. This way even though the editing control showing event get fired multiple times, we can be assured that our editing control is being wired only one time.
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
//UnWire the code
combo.SelectedIndexChanged -=new EventHandler(combo_SelectedIndexChanged);
//Wire the code
combo.SelectedIndexChanged +=new EventHandler(combo_SelectedIndexChanged);
}
-
Monday, March 24, 2008 7:19 PM
Here is a slightly more complete example.
The difference in this example to what has previously been discussed is that we do not keep a reference to the control in a private variable. There is no need to do that, and doing so produces a lot of potential for errors. Since the DataGridView is managing the combobox controls, there may be many of these controls, and even the same "logical control" (ie, to the user, the same combo box in the same row), may get destroyed or rebuilt at any time, by the DGV. From our perspective, outside of the DataGridView, the only thing we are sure of is that the control referenced in the event args for EditingControlShowing is currently the one that the user is using...
Instead of a private reference to the combobox, we keep a private reference to the EventHandler delegate for our SelectionChangeComitted event. There's no point in creating a two new delegates every time the control is clicked.
I use this technique in my apps to control the row state conditionally based on the selections in various comboboxs. I call _dataGridView.EndEdit() in the SelectionChangeCommited event handler, to allow the other cells to react to the selection.
Hope that helps,
Troy
Code Snippetpublic class Example
{
/// <summary> /// Constructor /// </summary> public Example(){
new DataGridView();_dataGridView =
// setup the datagridview here.
// hook up editing control showing event_dataGridView.EditingControlShowing +=
new DataGridViewEditingControlShowingEventHandler(_dataGridView_EditingControlShowing);// create a delegate for the method that will handle the event
_comboBoxSelectDelegate =
new EventHandler(combo_SelectionChangeCommitted);}
private DataGridView _dataGridView; private EventHandler _comboBoxSelectDelegate;void _dataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
// get the control from the event args.
ComboBox combo = e.Control as ComboBox;
if (combo != null){
// remove the event subscription if it exists.combo.SelectionChangeCommitted -= comboSelectDelegate;
// add a subscription to the eventcombo.SelectionChangeCommitted += comboSelectDelegate;
}
}
void combo_SelectionChangeCommitted(object sender, EventArgs e)
{
// handle the event.
ComboBox combo = sender as ComboBox;if (combo != null)
{
MessageBox.Show(
string.Format("The combobox selected index is: {0}", combo.SelectedIndex)
);
}
}
}
-
Sunday, November 15, 2009 3:50 AM
Works great! Thank you!
-
Wednesday, April 06, 2011 12:30 PMDim flag As Boolean = False
Private Sub DataGridView1_EditingControlShowing(ByVal sender As System.Object, ByVal e As DataGridViewEditingControlShowingEventArgs) Handles dgv_assign.EditingControlShowing
If flag = False Then
Dim editingComboBox As ComboBox = e.Control
AddHandler editingComboBox.SelectionChangeCommitted, AddressOf Me.editingComboBox_SelectedIndexChanged
flag = True
End If
End Sub
Private Sub editingComboBox_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Try
Dim r_index, c_index As Integer
r_index = dgv_assign.SelectedCells(0).RowIndex
c_index = dgv_assign.SelectedCells(0).ColumnIndex
If dgv_assign.Columns(c_index).name = col_enterby.Name Then
Dim manager As String = Convert.ToString(dgv_assign.Rows(r_index).Cells(col_enterby.Name).EditedFormattedValue)
If IsNothing(ds_pmd.Tables("Load")) Then
LoadAssignes(manager)
Else
Dim dr() As DataRow = ds_pmd.Tables("Load").Select("pmd_manager='" & manager & "'")
If dr.Length = 0 Then
LoadAssignes(manager)
Else
BindingSource1.Filter = "pmd_manager='" & manager & "'"
End If
End If
End If
Catch ex As Exception
PARAM_Class_Library.Modules.ParamGlobal.CreateLogFile("dgv_assign_CellValueChanged : " & ex.Message, LogFilePath)
MessageBox.Show("dgv_assign_CellValueChanged: " & ex.Message, project_name, MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub -
Saturday, August 18, 2012 10:56 PM
Hi Troy,
I believe your above solution that uses a private reference to the EventHadler delegate is a very beatiful way to solve the problem resulted in handling SelectionChangeCommitted event. I got the same problem when I tried to handle the same event. But I can't translate your above solution in C# into VB. Can you or anybody else translate the solution for me?
Thanks!
Lao Fu
/Chengde Fu/


