I have a combo box which will update its data bound property when the SelectedIndexChanged, not just when the SelectedValueChanged. I.e. if a user selects a new value in the combo box, they don't then have to remove focus from the combo box in order for the PropertyChanged event to fire.
This was based on this answer: https://stackoverflow.com/a/8475679
/// <summary>
/// If the combo box value has changed, force the new value to be written to the data bound property.
/// Otherwise the value will only be written if focus is lost.
/// </summary>
private void ComboBoxSelectedIndexChanged(object sender, EventArgs e)
{
var comboBox = sender as ComboBox;
if (comboBox != null && comboBox.DataBindings.Count > 0)
{
comboBox.DataBindings[0].WriteValue();
}
}
However, I would now like to achieve this for combo boxes that are part of a DataGridView control. So far I have this:
private void GridEditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is ComboBox)
{
((ComboBox)e.Control).SelectedIndexChanged -= ComboBoxSelectedIndexChanged;
((ComboBox)e.Control).SelectedIndexChanged += ComboBoxSelectedIndexChanged;
}
}
which is based on this answer: https://stackoverflow.com/a/4154804/1061602, this successfully wires up my original ComboBoxSelectedIndexChanged event handler to the combo boxes in the grid.
However, this time, the DataBindings collection on the ComboBox is empty, so I need to find another way of doing this.
Any ideas?
EDIT
Attempted:
SendKeys.Send("~");
I.e. simulating pressing Enter, which confirms the value, focus leaves the combo box cell, and the data bound property is updated.
But this seemed to sometimes keep firing repeatedly, not sure why. Also it can't be used with EditMode.EditOnEnter as then it just instantly closes the combo box.
Sending TAB has the same effect.
Also tried
this.myGrid.EndEdit()
but this results in the value not be changed itself. Also if I call this.myGrid.BeginEdit()
programmatically then I get an 'object reference not set to an instance of an object' error when trying to BeginEdit after previously calling EndEdit...
EDIT 2
Leading in from the previous edit. I have set the grid EditMode to EditProgrammatically, and then calling this.myGrid.BeginEdit()
in the CellClick event handler.
Now the following code works:
/// <summary>
/// If the cell value has changed, force the new value to be written to the data bound property.
/// Otherwise the value will only be written if focus is lost.
/// </summary>
private void CellValueChanged(object sender, EventArgs e)
{
if (this.formsGrid.CurrentCell is DataGridViewCheckBoxCell)
{
SendKeys.Send("~");
}
if (sender is ComboBox)
{
if (this.formsGrid.EditingControl.Visible)
{
SendKeys.Send("~");
}
}
}
I was finding that the CellValueChanged event, which I attached to the combo box control in the EditingControlShowing event, was firing multiple times after clicking the combo box to enter edit mode. Why, I'm not sure.
I was able to avoid the mess by only sending the ENTER keypress once the editing control itself was visible. That way I could be sure that the CellValueChanged event was being fired because I just changed the value of the combo box).
This works fine, but I'm still not 100% happy with this technique.