I have two related issues here with my derived class.
I am trying to add a SelectedIndexChanged
event handler. It is certainly getting called:
class DataGridViewColourComboBoxCell : DataGridViewComboBoxCell
{
public override void InitializeEditingControl(int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle)
{
// Set the value of the editing control to the current cell value.
base.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle);
DataGridViewColourComboBoxEditingControl ctl =
DataGridView.EditingControl as DataGridViewColourComboBoxEditingControl;
// Use the default row value when Value property is null.
if (this.Value == null)
{
ctl.SelectedIndex = (int)this.DefaultNewRowValue;
}
else
{
ctl.SelectedItem = Find(this.Value.ToString());
try
{
ctl.SelectedIndexChanged -= new EventHandler(SelectedIndexChanged);
}
catch { }
ctl.SelectedIndexChanged += new EventHandler(SelectedIndexChanged);
}
}
}
private void SelectedIndexChanged(object sender, EventArgs e)
{
DataGridViewColourComboBoxEditingControl ctl = (DataGridViewColourComboBoxEditingControl)sender;
MessageBox.Show(ctl.SelectedIndex.ToString());
}
But I have two issues:
- The application seems to be piggy-backing the event handler each time I select on a different combo in the grid, because each time I receive one more popup message than before (1, then 2, then 3 and so on). I thought the use of the try/catch block would prevent this.
I have fixed item 1. I was adding the event handler in the wrong place. I needed it here:
public class DataGridViewColourComboBoxEditingControl : DataGridViewComboBoxEditingControl
{
public DataGridViewColourComboBoxEditingControl() : base()
{
DrawMode = DrawMode.OwnerDrawFixed;
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
//base.OnDrawItem(e);
//....
}
protected override void OnSelectedIndexChanged(EventArgs e)
{
MessageBox.Show(SelectedIndex.ToString());
base.OnSelectedIndexChanged(e);
}
}
- It is not fireing exactly as I would like. I only want to know when the user has picked an entry from the displayed dropped down list. At the moment the above event handler is also fired when setting focus to the next cell.
But item 2 is still an issue. Event just clicking another cell causing the event to fire (note that I have set my grid to edit on click). But a single click on the cell will not show the dropdown anyway. I don't want it to fire in that context. It has to be a result from a choice from the dropdownlist.
I have seen this: How to handle SelectedIndexChanged event for a ComboBox?
But I don't want to do things in the grid. I want to do things in my derived classes. Basically I want to detect when they show the dropdown and click the first item. If they click the first item it should show a form (kind of acting like a button).
Update:
I believe I may have found my solution:
public class DataGridViewColourComboBoxEditingControl : DataGridViewComboBoxEditingControl
{
public DataGridViewColourComboBoxEditingControl() : base()
{
DrawMode = DrawMode.OwnerDrawFixed;
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
//base.OnDrawItem(e);
//....
}
protected override void OnDropDownClosed(EventArgs e)
{
if(SelectedIndex == 0) // Display the pop up
MessageBox.Show("Display pop up colour dialog");
base.OnDropDownClosed(e);
}
}
I needed to use OnDropDownClosed
. Only problem with this solution is that the entry has already been selected in the cell. Since I want the first item in the combo to act like a button the idea is that if they select that, it displays a dialogue (where they choose a different colour not already in the combo) and it add it to the combo and select it. At the moment, if I manually add SelectedIndex = 5;
in the handler (and I had actually picked index 4) it flashes the cell for index 4 first and then index 5. Make sense?