c# - WinForms ComboBox SelectedIndexChanged 在键入几个字符后按 Alt+Down 时不会触发

原文 标签 c# winforms events combobox

总之

当我在 ComboBox 中键入一个字符时,按 Alt+Down,然后按 Enter 或 Tab,即使 SelectedIndex 值发生变化,SelectedIndexChanged 事件也不会触发!为什么事件不触发?

更新
如果您键入一个字符,按 Alt+Down,然后键入 Esc,则会出现同样的错误。您会期望 Esc 取消更改。但是, SelectedIndex 确实发生了变化,并且 SelectedIndexChanged 事件不会触发。

如果您只键入 Alt+Down,使用箭头键浏览到一个条目,然后键入 Esc,会发生什么情况?是否应将所选索引设置回其原始值?

没那么短

我有一个带有 ComboBox 的 WinForm 应用程序。 ComboBox 的 SelectedIndexChanged 事件连接到在 Label 控件中显示 SelectedItem 的事件处理程序。 ComboBox 的 Items 集合具有三个值:“一”、“二”和“三”。

  • 当我用鼠标选择一个项目时,事件会触发。
  • 当我滚动鼠标时,事件触发。
  • 当我使用 Alt+Down 扩展组合框并使用 Up 和 Down 浏览项目时,事件会触发。
  • 但是...当我输入值的第一个字符,然后按 Alt+Down,然后按 Enter 或 Tab 时,该值确实被选中并显示在组合框中,但不会触发该事件。

  • 我还添加了一个显示 SelectedIndex 的按钮。它显示 SelectedIndex 已更改。因此,即使 SelectedIndex 确实发生了变化,SelectedIndexChanged 事件也不会触发!

    如果我只是输入一个有效的值,如 One该事件也不会触发,但在这种情况下,单击按钮会显示 SelectedIndex 确实没有改变。所以在这种情况下,行为是正常的。

    要重现,请创建一个 Form 并添加一个 ComboBox、一个标签和一个按钮。将以下代码放在 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);
            }
        }
    }
    

    最佳答案

    我已经尝试了几次谷歌搜索,以便找到一个明确的答案,但之前没有找到。刚才我发现了一个线程,实际上是指有关该问题的 Microsoft 知识库文章。文章 KB948869描述了问题。

    知识库文章建议创建您自己的组合框并覆盖 ProcessDialogKey 方法。

    using System.Windows.Forms;
    
    public class MyComboBox : ComboBox
    {
        protected override bool ProcessDialogKey(Keys keyData)
        {
            if (keyData == Keys.Tab)
                this.DroppedDown = false;
            return base.ProcessDialogKey(keyData);
        }
    }
    

    我试过了,但不幸的是,它似乎没有任何效果。这有点奇怪。我希望知识库文章中描述的解决方法是准确的。

    不过,我找到了另一种解决方法,即改用 DropDownClosed 事件。
    private void comboBox1_DropDownClosed(object sender, EventArgs e)
    {
        label1.Text = "DroDownClosed Selected index: " + comboBox1.SelectedIndex;
    }
    

    这似乎确实有效,但仅在使用 DropDownStyle.DropDown 时才有效。当您将 DropDownStyle 设置为 DropDownList 时,键入字符不会触发 DropDownClosed(因为在这种情况下没有实际下拉列表)。只有当您实际打开下拉列表并选择一个值时,才会触发 DropDownClosed 事件。

    因此,这两个选项都不是一个很好的答案。

    更新
    我什至尝试覆盖 MyComboBox 中的 SelectedIndex 属性,让它调用 OnSelectedIndexChanged(EventArgs.Empty) .键入一个字符并按 Alt+Down 后,将执行 setter,但它将值设置为 -1,它已经是。按 T​​ab 后,setter 不会再次执行,尽管 SelectedIndex 值确实发生了变化。看起来 ComboBox 正在直接更改 SelectedIndex 的支持字段,绕过设置。我相信这样的事情可能也发生在真正的 ComboBox 中。

    关于c# - WinForms ComboBox SelectedIndexChanged 在键入几个字符后按 Alt+Down 时不会触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4759579/

    相关文章:

    c# - 中继命令没有被触发

    winforms - .net windows 窗体和选择 Vista 字体

    javascript - 主干多事件处理程序问题 : only one method called for the same event

    iphone - 合成点击不会切换应用程序的菜单栏 (Mac OS X)

    c# - 普通TextBox中的自动文本更正

    c# - Autofac:如何加载被引用但未直接使用的程序集

    C# 用户定义的 CSV 映射到 POCO

    c# - 如何使用 HttpClient 读取 XML 响应?

    c# - 如何限制 Winforms MaskedTextbox 中的值

    linux - 将Windowsforms项目从Visual Studio迁移到Linux上的monodevelop,没有错误。为什么应用程序运行速度很慢?