以编程方式选择索引0(从-1)时,组合框未激发SelectedIndexChanged

本文关键字:组合 SelectedIndexChanged 选择 方式 编程 索引 | 更新日期: 2023-09-27 17:57:38

我有一个组合框,用于使用SelectIndexChanged事件捕获用户和程序更改。

清除并重新加载绑定到组合框的列表将自然触发索引为-1的事件处理程序。

但随后选择的索引=-1

combobox1.SelectedIndex = 0 ; // will NOT fire the event.

但是

combobox1.SelectedIndex = 1 ; // or higher number WILL fire the event.

在这两种情况下,我都在以编程方式更改selextedindex,并期望触发该事件。

我用一个简单的表格验证了行为。

namespace cmbTest
{
    public partial class Form1 : Form
    {
        private BindingList<string> items = new BindingList<string>();
        public Form1()
        {
            InitializeComponent();
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            comboBox1.DataSource = items;
            loadItems();
        }
        private void loadItems()
        {
            items.Add("chair");
            items.Add("table");
            items.Add("coffemug");
        }
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            MessageBox.Show("Fired with selected item index:" + comboBox1.SelectedIndex);
        }
        private void button1_Click(object sender, EventArgs e)
        {
            int index = comboBox1.SelectedIndex;
            // Clear and reload items for whatever reason.
            items.Clear();
            loadItems();
            // try select old item index; if it doesnt exists, leave it.
            try { comboBox1.SelectedIndex = index; }
            catch { }
        }


    }
}

表单有一个组合框1和一个按钮1。

编辑清晰(我希望):

  1. 运行程序
  2. 选择"椅子"。消息"使用所选项目索引激发:0"
  3. 点击按钮。消息"使用所选项目索引激发:-1"
  4. 选择"表"。消息"使用所选项目索引激发:1"
  5. 点击按钮。消息"用所选项目索引激发:-1"AND"使用所选项目索引激发:1"

当"椅子"也被选中时,当点击按钮时,我预计会收到两条消息,因为我通过编程将索引更改为0。

那么,为什么这没有像我期望的那样起作用,什么是可以接受的变通方法呢?

以编程方式选择索引0(从-1)时,组合框未激发SelectedIndexChanged

当您的第一个项目添加到项目集合时,索引会自动更改为0。这就是为什么当您的上一个索引保存为0,然后使用此行comboBox1.SelectedIndex = index;再次设置它时,索引不会更改。这就是为什么该活动没有被启动。

查看ComboBox的源代码,有两种情况下不会触发事件:抛出表达式,或者将索引设置为与原来相同的值。

如果你真的想破解一下,你可以这样做:

int index = comboBox1.SelectedIndex;
// Clear and reload items for whatever reason.
items.Clear();
loadItems();
if(comboBox1.SelectedIndex == index)
{
    comboBox1.SelectedIndexChanged -= comboBox1_SelectedIndexChanged;
    comboBox1.SelectedIndex = -1;
    comboBox1.SelectedIndexChanged += comboBox1_SelectedIndexChanged;
}
// try select old item index; if it doesnt exists, leave it.
try { comboBox1.SelectedIndex = index; }
catch
{
}