【问题标题】:ComboBox SelectedIndexChanged event: how to get the previously selected index?ComboBox SelectedIndexChanged 事件:如何获取之前选择的索引?
【发布时间】:2025-12-04 19:05:02
【问题描述】:

我有一个用户控件,它有一个 ComboBox 和一个 SelectedIndexChanged 事件处理程序。在事件处理程序中,我需要能够分辨出之前选择的索引是什么...谁能指出我正确的方向?

private void cboTargetMode_SelectedIndexChanged(object sender, EventArgs e)
{
    // need to get the previously selected index and do some handling here...
    // ... some handler code here ...


    switch (cboTargetMode.SelectedIndex)
    {
        case 1:  // ..... some code here...
            break;
        case 2:  // ..... some code here...
            break;
        case 3:  // ..... some code here...
            break;
        default: // ..... some code here...
            break;
    }
}

【问题讨论】:

    标签: c# winforms .net-3.5


    【解决方案1】:

    没有内置任何内容,您需要监听此事件并在实例变量中跟踪。

    使用 -1 作为未初始化的“最后一个索引”,所以在第一次通过时设置它但不要使用它。后续通过你使用它并设置它。

    您始终可以使用您自己的派生 ComboBox 类并覆盖 OnSelectedIndexChanged 并公开 PreviousSelectedIndex 属性来执行此操作。这样,它就不会与表单紧密耦合。或者,您可以使用事件来执行此操作,它也可以作为extender provider 实现。

    【讨论】:

    • 不应该是“实例变量”而不是“类变量”吗?
    • @FrankSchmitt 正在寻找一个徽章来挖掘一个近 8 年的帖子? ;-) 但是是的,你是对的,我已经修改了我的答案。
    • @AdamHouldsworth 谢谢。不,我(目前)不是在寻找徽章:-)
    【解决方案2】:

    我猜你必须将当前的(稍后将成为以前的)存储到一个变量中,以便像缓存或类似的东西一样使用它。

    private void cboTargetMode_SelectedIndexChanged(object sender, EventArgs e) {
        // need to get the previously selected index and do some handling here...
        // ... some handler code here ...
    
        // Assuming that the variable PreviousSelectedIndex is declared in the class with value -1.
        if (PreviousSelectedIndex < 0)
            PreviousSelectedIndex = cbo.TargetMode.SelectedIndex;
        else
            // Do some handling here...
    
        switch (cboTargetMode.SelectedIndex) {
            case 1:  // ..... some code here...
                break;
            case 2:  // ..... some code here...
                break;
            case 3:  // ..... some code here...
                break;
            default: // ..... some code here...
                break;
        }
    }
    

    这是你已经想到的吗?

    否则,可能会处理Control.Validating 事件?我只是不能说这个事件是发生在SelectedIndexChanged 事件之前还是之后。 =(

    【讨论】:

      【解决方案3】:

      comboBox_SelectionChangeCommitted 事件怎么样?选择完成后调用此方法,菜单折叠但项目未完全更改。所以只需阅读 comboBox.SelectedText 或 comboBox.SelectedValue 甚至 comboBox.SelectedIndex

      private void comboBox1_SelectionChangeCommitted(object sender, EventArgs e)
      {
          int prevIndex = comboBox1.SelectedIndex;
      }
      

      【讨论】:

      • @Zekeriya,这是从 6 年前开始的,但我通过双向绑定 SelectedItem 并管理视图模型上绑定属性的 setter 中的先前选择解决了这个问题.说实话,这被证明是更好的方法,因为它更容易做到,并且与控件无关——这意味着我不需要为我将绑定的每个不同控件编写一些处理程序代码列出来。
      • 好的,上个月我需要一个解决这个问题的方法,但接受的 awnser 对我不起作用。以某种方式,您当前的回复也没有奏效,但我稍后会检查...无论如何感谢您的回复:)
      • 我们@my shop 使用的当前 MVVM 理念是避免转换器,避免行为(除非绝对必要)并尝试让视图模型做更多的工作 - 即制作 it i> 提供 SelectedItem 等。
      【解决方案4】:

      这个是用来获取当前选中的索引的,我刚好需要,没找到,希望对你有帮助

       private void lsbx_layers_SelectedIndexChanged(object sender, EventArgs e)
              {
                  int i = lsbx_layers.SelectedIndices[0];//selected index
                  MessageBox.Show("Selected item at index : " + i);
              }
      

      【讨论】:

        【解决方案5】:

        我遇到了与此类似的问题,我使用

        将所有组合框设置为“自动完成”
        ComboBox.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
        ComboBox.AutoCompleteSource = AutoCompleteSource.ListItems;
        

        我循环并设置了他们所有的 lostFocus 事件:

        foreach(Control control in this.Controls)
        {
            if(control is ComboBox)
           {
                ((ComboBox)control).LostFocus += ComboBox_LostFocus;
           }
        }
        

        并且有一个字典对象来保存旧值

        public Dictionary<string, int> comboBoxOldValues = new Dictionary<string, int>();
        

        然后最后确保值存在或设置为旧索引,然后保存到字典

        private void ComboBox_LostFocus(object sender, EventArgs e)
        {
            ComboBox comboBox = (ComboBox)sender;
        
            if (comboBox.DataSource is List<YourDataType>)
            {
                if (((List<YourDataType>)comboBox.DataSource).Count(x => x.YourValueMember == (YourValueMemberType)comboBox.SelectedValue) == 0)
                {
                    if (comboBoxOldValues.Keys.Count(x => x == comboBox.Name) > 0)
                    {
                        comboBox.SelectedIndex = comboBoxOldValues[comboBox.Name];
                    }
                    else
                        comboBox.SelectedIndex = -1;
                }
            }            
        
            if (comboBoxOldValues.Keys.Count(x => x == comboBox.Name) > 0)
            {
                comboBoxOldValues[comboBox.Name] = comboBox.SelectedIndex;
            }
            else
                comboBoxOldValues.Add(comboBox.Name,  comboBox.SelectedIndex);
        
            if (comboBox.SelectedIndex == -1)
                comboBox.Text = string.Empty;
        }
        

        【讨论】:

          【解决方案6】:

          您可以在DropDown 事件中获取并存储旧值。然后在SelectionChangeCommitted 事件中恢复到那个旧值(如果需要)。

          【讨论】: