In short
When I type a character in a ComboBox, press Alt+Down followed by Enter or Tab, the SelectedIndexChanged event doesn’t fire, even though the SelectedIndex value does change! Why doesn’t the event fire?
Update
The same error occurs if you type a character, press Alt+Down and then type Esc. You would expect the Esc to cancel the change. However, the SelectedIndex does change, and the SelectedIndexChanged event doesn’t fire.
What should happen if you just type Alt+Down, use the arrow keys to browse to an entry, and then type Esc? Should the selected index be set back to its original value?
Not so short
I have a WinForm application with a ComboBox on it. The ComboBox’ SelectedIndexChanged event is wired up to a event handler that shows the SelectedItem in a Label control. The ComboBox’ Items collection has three values: “One”, “Two”, and “Three”.
- When I select an item with the mouse, the event fires.
- When I scroll the mouse, the event fires.
- When I use Alt+Down to expand the combobox and walk through the items with Up and Down, the event fires.
- But… When I type in the first character of a value, then press Alt+Down, followed by Enter or Tab, the value does get selected and is shown in the combobox, but the event doesn’t fire.
I’ve also added a button that shows the SelectedIndex. It shows the SelectedIndex has changed. So even though the SelectedIndex does change, the SelectedIndexChanged event does not fire!
If I just type in a valid value like One the event doesn’t fire either, but in that case a click on the button reveals the SelectedIndex indeed hasn’t changed. So in that case the behavior is normal.
To reproduce, create a Form and add a ComboBox, a Label and a Button. Place the following code in the Form1.cs:
using System;
using System.Windows.Forms;
namespace ComboBoxSelectedIndexChanged
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
comboBox1.Items.AddRange(new object[] {
"One",
"Two",
"Three"
});
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
label1.Text = "Selected index: " + comboBox1.SelectedIndex;
}
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Selected item: " + comboBox1.SelectedItem +
"\nSelected index: " + comboBox1.SelectedIndex);
}
}
}
The appropriate DropDown property value here is DropDownList. It doesn’t have this problem.
Coming up with a workaround for your specific problem with the DropDown style set to DropDown is quite difficult. It allows the user type arbitrary text and even a perfect match with one of the dropdown items doesn’t change the SelectedIndex. You’d have to implement the Validating event and look for a match yourself. The DropDownClosed event would be good for your specific scenario. But really, always use DropDownList if you want perfect matches.