Rekshino
Rekshino

Reputation: 7325

Prevent bypassing SelectedIndexChanged in ComboBox

I was surprised, that SelectedIndexChanged on a ComboBox with ComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList can be bypassed by changing the shown value to another one.

Here are steps to reproduce the case:

What would be your offer to prevent this undesirable behavior. Tab key must not be suppressed and ComboBox.SelectedIndexChanged must be triggered on change.

Some code for copy-paste:

public Form1()
{
    InitializeComponent();

    comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
    comboBox1.Items.Add(1);
    comboBox1.Items.Add(2);
    comboBox1.Items.Add(3);
    comboBox1.Items.Add(4);
    comboBox1.Items.Add(5);
    
    comboBox1.SelectedIndexChanged += ComboBox1_SelectedIndexChanged;
}
private void ComboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
    comboBox1.SelectedIndex = 0;
}

Upvotes: 2

Views: 803

Answers (2)

Rekshino
Rekshino

Reputation: 7325

I have solved it with derived control:

class ModifiedComboBox : ComboBox
{
    private object _lastSelectedItem = null;

    protected override void OnDropDownClosed(EventArgs e)
    {
        if(SelectedItem != _lastSelectedItem)
        {
            OnSelectedIndexChanged(new EventArgs());
        }
        base.OnDropDownClosed(e);
    }

    protected override void OnSelectedIndexChanged(EventArgs e)
    {
        _lastSelectedItem = SelectedItem;
        base.OnSelectedIndexChanged(e);
    }
}

Upvotes: 1

JohnG
JohnG

Reputation: 9479

It is unclear “why” you want this odd behavior from a ComboBox; however, it appears you did not look a little closer at the ComboBox events.

It is true what you describe... When the user presses the Tab key “while” still holding the mouse button on a selection in the combo box… then the ComboBoxes SelectedIndexChanged event does NOT fire since the control is still IN the process of “selecting” a different index.

However, the ComboBoxes Validating and Leave events DO fire in the above situation. Instead of creating another control for this, wiring up the combo boxes Validating or Leave event will fix what you describe. Something like…

The current SelectedIndexChanged for normal situations…

private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) {
  comboBox1.SelectedIndexChanged -= new System.EventHandler(comboBox1_SelectedIndexChanged);
  comboBox1.SelectedIndex = 0;
  comboBox1.SelectedIndexChanged += new System.EventHandler(comboBox1_SelectedIndexChanged);
}

Then, using the ComboBoxes Leave event for the “special” case when the user Tabs out of the combo box.

private void comboBox1_Leave(object sender, EventArgs e) {
  comboBox1.SelectedIndexChanged -= new System.EventHandler(comboBox1_SelectedIndexChanged);
  comboBox1.SelectedIndex = 0;
  comboBox1.SelectedIndexChanged += new System.EventHandler(comboBox1_SelectedIndexChanged);
}

Upvotes: 0

Related Questions