views:

59

answers:

2

I have a windows form. It has a ComboBox and a DataGrid

I have a Leave event on my combobox and I have a double click event on my datagrid row

The idea is that on leaving the combobox, if the value of the combo box changed than use the new value to reload the datagrid.

Let's say the combobox is displaying a value of 1 and for that value there are 5 records displayed in the DataGrid. Now the user enters 2 in the combobox and tabs away. great in my leave event I see that the value has changed and I reload the Datagrid with all the records for that value

But if the user enters 2 and double clicks on existing records for the value 1, than the leave event reloads the datagrid and than the double click event FIRES.

How do I find a list of pending events and cancel each and every one of them, if the datagrid has been reloaded. thanks for any help

+1  A: 

Instead of using the Leave Event, try SelectedIndexChanged Event, that would be fired before the datagrids doubleclick event. The downside is if the user is scrolling the combobox with the keyboard, then it will fire 5 times if the user scrolls 5 steps down in the combobox.

Another solution would be to store a local variable lComboEntered=true when entering the combo and set the value to false when the leave event fires. And in the datagrid doubleclick event check if the lComboEntered=false before doing anyting.

Stefan
In my leave event routine, if the combobox value has changed than i reload the datagrid AND set a CancelDoubleClick Flag to TRUE. Inside my datagrid doubleclick routine, I check this flag and cancel the event if it is true. This works fine if I change value in my combobox and double click a row without doing anything else. But if i enter a value in the combobox and simply tab away than i have to double click the datagrid TWICE. where else Could i reset that flag to FALSE.
CodingJoy
+1  A: 

You've got an event order problem, the DataGridView.Enter event fires too soon. This can be cleanly solved by delaying event actions with the Control.BeginInvoke() method. Its delegate target fires as soon as your program re-enters the message loop. In other words, after all pending events have fired. Make it look similar to this:

private bool selectionDirty;

private void comboBox1_TextChanged(object sender, EventArgs e) {
  selectionDirty = true;
}

private void dataGridView1_Enter(object sender, EventArgs e) {
  this.BeginInvoke(new Action(() => selectionDirty = false));
}

private void dataGridView1_CellMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e) {
  if (selectionDirty) return;
  // etc...
}
Hans Passant
i'll give this a try Monday morning
CodingJoy
I dont think this will work. because upon entering the datagrid, there is no guarantee that it was reloaded.
CodingJoy
I need Jon Skeet or Ayende here to help me out
CodingJoy