【问题标题】:How to know if the AutoComplete listbox on an TextBox is open?如何知道 TextBox 上的自动完成列表框是否打开?
【发布时间】:2017-01-09 15:44:54
【问题描述】:

我有一个带有 2 个文本框的表单。第一个为其自动完成设置了一个自定义源,如下所示:

textBox1.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
textBox1.AutoCompleteSource = AutoCompleteSource.CustomSource;
textBox1.AutoCompleteCustomSource = GetUserNames();

GetUserNames() 方法返回 AutoCompleteCustomSource,这一切都很好。

当此表单在第一个文本框上打开焦点时,用户可以输入或从自动完成中进行选择,效果很好。

两个文本框都有一个 onKeyDown 事件,在这种情况下,它们应该使用两个文本框的值进行一些验证。

我想 keydown 仅在自动完成列表框关闭时按下 ENTER 时进行验证。

这样看:
用户开始输入,出现一个列表,用户从列表中选择一个项目并按 Enter 确认他的选择,然后他想按 TAB 转到下一个文本框。
但是当他在自动完成列表中选择一个项目后按 ENTER 键时,keyDown 事件已经触发。在这个阶段,keydown 事件不应该触发,ENTER 应该只确认自动完成列表中的选择。

有没有办法在 keydown 中检测到在自动完成列表仍然打开时按下了 ENTER ? 或者有没有办法在自动完成列表打开时禁用 keydown 事件?

编辑:
从 cmets 我尝试了这个链接中的答案https://stackoverflow.com/a/40915048/3110834 不幸的是,它在这种情况下不起作用,但它告诉我在自动完成建议上按 Enter 会做两件事:

  1. 关闭自动完成窗口
  2. 触发文本框的 keydown 事件

所以我需要找到一种方法来停止 keydown 事件,以便在自动完成窗口上按 enter 时触发文本框。

编辑:
事情比我想象的要糟糕得多。
当您打开自动建议框然后单击建议的项目以选择它时,keydown 事件也会触发并且它的 KeyCode 中有 Keys.Enter !从什么时候开始单击等于击键?
我该如何阻止这个?这是一个错误吗?

【问题讨论】:

  • Here 是解决方案,使用 VB.NET 实现:Detect when TextBox autocomplete list is showing
  • @RezaAghaei 我正在尝试将答案转换为 C#,但我被困在 New EnumThreadDelegate(AddressOf Me.EnumThreadCallback), IntPtr.Zero) 上。 AddresOf 的 c# 方法是什么?我在这里找到了很多关于它的文章,但它们不起作用,或者我不明白在这种情况下如何使用它们
  • 我终于把它转换成 c# 但 IsWindowVisible() 总是返回 false。知道是什么原因造成的吗?调试 EnumThreadCallBack 时,正确的类名就在那里
  • @RezaAghaei 感谢您的回答,但这对我没有帮助,似乎在自动建议下拉菜单上按 Enter 时,下拉菜单首先关闭,然后文本框的 keydown 触发。然后 IsWindowVisisble 将返回 false。

标签: winforms autocomplete


【解决方案1】:

我遇到了同样的问题,我按照链接https://stackoverflow.com/a/40915048/3110834中的方法进行操作

如果您尝试在 Keydown 事件期间评估是否有打开的列表,它总是会返回 false,因为该事件已经关闭了列表。

相反,我观察 PreviewKeyDown 事件来评估 AutoComplete 列表是否打开,如果它是打开的,我取消订阅 KeyDown 事件(在我的情况下仅使用 Enter 键),如果列表关闭,我再次重新订阅它

private void tbxAND_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
    {
        if (e.KeyCode == Keys.Enter)
        {
            if (IsAutoCompleteOpen())
            {
                tbxAND.KeyDown -= tbxAND_KeyDown;
            }
            else
            {
                tbxAND.KeyDown += tbxAND_KeyDown;
            }
        }
    }

注意 IsAutoCompleteOpen() 会启动代码来枚举 openlist。

如果您仍需要捕获其他键,这可能不是此特定情况的完整解决方案,但我想留下提示以防其他人遇到此问题。

【讨论】:

  • 似乎是我想尝试的一个想法,谢谢
猜你喜欢
  • 1970-01-01
  • 2018-11-19
  • 2011-09-12
  • 1970-01-01
  • 1970-01-01
  • 2010-10-31
  • 2016-08-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多