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

标签 c# winforms events combobox

简而言之

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

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

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


没那么短

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

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

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

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


要重现,请创建一个表单并添加一个组合框、一个标签和一个按钮。将以下代码放在 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# - Xamarin.Forms:如何将资源中的图像加载到字节数组中?

c# - 将控件属性(例如颜色)数据绑定(bind)到未显示的字段

c# - 不使用 Microsoft.Win32 打开文件对话框

c# - 如何确定事件是由用户操作还是代码触发的?

javascript - 为内容更改创建一个 jQuery 特殊事件

c# - 此 PHP 加密代码中使用的函数的 C# 等效项是什么?

c# - 从 c# winforms 应用程序将输出写入控制台

c# - RSA 弓箭手 : How to execute a Data Feed from an Application

c# - 验证和更改用户密码

powershell - 关于 ISE 与带有 SystemEvents 的控制台的问题