防止绕过 ComboBox 中的 SelectedIndexChanged

Prevent bypassing SelectedIndexChanged in ComboBox

我很惊讶,ComboBoxComboBox.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList 上的 SelectedIndexChanged 可以通过将显示值更改为另一个来绕过。

重现案例的步骤如下:

你会提供什么来防止这种不良行为。 Tab 键不得被抑制,ComboBox.SelectedIndexChanged 必须在更改时触发。

一些用于复制粘贴的代码:

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;
}

我已经用派生控件解决了:

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);
    }
}

目前尚不清楚“为什么”您希望 ComboBox 出现这种奇怪的行为;但是,您似乎没有仔细观察 ComboBox 事件。

你描述的是真的...当用户按下 Tab 键时“同时”仍将鼠标按钮放在组合框中的选择上...然后 ComboBoxes SelectedIndexChanged 事件不会触发,因为控件仍在“选择”不同索引的过程中。

但是,ComboBoxes ValidatingLeave 事件确实会在上述情况下触发。而不是为此创建另一个控件,连接组合框 ValidatingLeave 事件将修复您所描述的内容。像……

正常情况下的电流SelectedIndexChanged……

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);
}

然后,使用 ComboBoxes Leave 事件处理用户 Tab 离开组合框时的“特殊”情况。

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);
}