2

I want to handle this event "SelectedIndexChanged" on a DataGridViewComboBoxColumn, and I set it on "EditingControlShowing" event of the gridview.

The problem : "SelectedIndexChanged" event is not fired on first attempt of selecting an Item from the comboBox, but after selecting that item for the second time the event is fired and everything works fine !

Here is the code:

private void dgvRequest_EditingControlShowing(object sender,
     DataGridViewEditingControlShowingEventArgs e)
{
    ComboBox combo = e.Control as ComboBox;

    if (combo != null)
    {
        if (dgvRequest.CurrentCell.ColumnIndex == col_ConfirmCmb.Index)
        {
            combo.SelectedIndexChanged -= combo_ConfirmSelectionChange;
            combo.SelectedIndexChanged += combo_ConfirmSelectionChange;

            return;
        }
    }
}


void combo_ConfirmSelectionChange(object sender, EventArgs e)
{
    if (dgvRequest.CurrentCell.ColumnIndex != col_ConfirmCmb.Index) return;

    ComboBox combo = sender as ComboBox;
    if (combo == null) return;

    MessageBox.Show(combo.SelectedText);// returns Null for the first time
}
Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
shahab
  • 71
  • 1
  • 5
  • 9

1 Answers1

6

Things get complicated since they optimized the DataGridView by only having one editing control for all the rows. Here's how I handled a similar situation:

First hook up a delegate to the EditControlShowing event:

myGrid.EditingControlShowing += new DataGridViewEditingControlShowingEventHandler(
                                    Grid_EditingControlShowing);
...

Then in the handler, hook up to the EditControl's SelectedValueChanged event:

void Grid_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
    ComboBox combo = e.Control as ComboBox;
    if (combo != null)
    {
        // the event to handle combo changes
        EventHandler comboDelegate = new EventHandler(
            (cbSender, args) =>
            {
                DoSomeStuff();
            });

        // register the event with the editing control
        combo.SelectedValueChanged += comboDelegate;

        // since we don't want to add this event multiple times, when the 
        // editing control is hidden, we must remove the handler we added.
        EventHandler visibilityDelegate = null;
        visibilityDelegate = new EventHandler(
            (visSender, args) =>
            {
                // remove the handlers when the editing control is
                // no longer visible.
                if ((visSender as Control).Visible == false)
                {
                    combo.SelectedValueChanged -= comboDelegate;
                    visSender.VisibleChanged -= visibilityDelegate;
                }
            });

        (sender as DataGridView).EditingControl.VisibleChanged += 
           visibilityDelegate;

    }
}
Sam Trost
  • 2,173
  • 20
  • 26
  • Nice Snippet. It helped me out. – MoonKnight Aug 25 '11 at 13:10
  • when you write visSender in the second Lambda expression how is this defined? As this cannot be defined at runtime without doing some more contrived coding? Thanks very much... – MoonKnight Aug 25 '11 at 15:39
  • The definition of the EventHandler delegate is (object sender, EventArgs e). visSender is the object that triggered the EditingControl.VisibleChanged event. In this situation, the lambda is expecting it is the editing control that is triggering the visibility change. Does this answer your question? – Sam Trost Aug 26 '11 at 14:07
  • 1
    Yes I think it does. I have solved the issue now but in a different way. If you are interested the method is explained here . All the best. – MoonKnight Aug 26 '11 at 17:21