在WinForm文本框中处理箭头键事件而不覆盖原有功能

4

我有一个情况,我得到了一个WinForms TextBox实例,我想要给它添加自动完成功能。

我已经弄清楚了自动完成(字符串匹配+下拉菜单)的所有内容,并且目前它可靠地工作。

问题是如何使用键盘导航下拉菜单(这种UI通常都支持)。

自然的解决方案是处理TextBox的KeyDown事件(或类似事件),并相应地移动下拉菜单中的选项。但是,要做到这一点,您需要重写IsInputKey()事件以允许捕获箭头键事件。另一种方法是重写ProcessCmdKey()并在那里处理事件。这两种方法的问题是我不能覆盖任何东西,因为我无法替换TextBox实例。

编辑:假设我有以下代码:

void _textBox_KeyDown(object sender, KeyEventArgs e)
{
    if (_dropdown.Visible)
    {
        // TODO The stuff below fails because we need to either handle ProcessCmdKey or override IsInputKey
        switch (e.KeyCode)
        {
            case Keys.Tab:
                {
                    // click selected item
                    _dropdown.Items[GetSelectedItemIndex()].PerformClick();
                    break;
                }
            case Keys.Down:
                {
                    // select next (or first) item
                    int i = GetSelectedItemIndex() + 1;
                    if (i >= _dropdown.Items.Count) i = 0;
                    _dropdown.Items[i].Select();
                    break;
                }
            case Keys.Up:
                {
                    // select previous (or last) item
                    int i = GetSelectedItemIndex() - 1;
                    if (i < 0) i = _dropdown.Items.Count - 1;
                    _dropdown.Items[i].Select();
                    break;
                }
        }
    }
}

以上代码的问题在于,它从未被调用。箭头键事件从未被触发。更多信息请参考:上下左右箭头键不会触发KeyDown事件


2
你可以在 Form 级别上进行按键预览。或者你可以使用 keyboard hook - Sinatr
@Sinatr 预览确实是一种可能的解决方案... 有更好的方法吗?另外,你所说的钩子是什么意思? - Christian
我不理解...你有一个文本框和一个单独的下拉菜单,后者包含前者的自动完成条目?找到输入时,哪个会显示该条目?是下拉菜单吗?还是它也将加载到文本框中? - rory.ap
当用户选择文本框(将其聚焦)时,下拉列表会显示。输入任何内容都会更改下拉列表的值(过滤为匹配文本框搜索查询)。按箭头键更改下拉列表选择,一旦按下tab / return键,文本框将从下拉列表中获取值。问题是用户无法更改下拉列表的选择,因为文本框没有接收箭头键的关键事件。 - Christian
你好,Christian,你有解决方案吗?你是如何获得文本框的下拉控件的? - VRage
2个回答

0

希望我没有误解你,但这是一个解决方案吗:

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.KeyCode == Keys.Down)
    {
         // Place logic for textbox here
    }
}

我会在窗体上使用一个KeyDown事件,然后将按键代码与Keys.Down按键代码进行比较。 无效 请参见此处:上、下、左和右箭头键不触发KeyDown事件

您可以在此处查看反对该方法的原因:https://dev59.com/aXI-5IYBdhLWcg3w18V3。 - Christian
好的观点!那是一个有趣的问题。 - Jens
是的,不幸的是,这并没有看起来那么简单。 :/ - Christian
你应该在你的问题中包含引用的问题。 - Jens

0

我可能没有完全理解你的问题,但是这样的方法不会有效吗?

private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
    comboBox1.Text = //results of your matching algorithm.
}

private void textBox1_Validated(object sender, EventArgs e)
{
    textBox1.Text = (string) comboBox1.Text;
}

@Christian 嗯...有趣。在我提供的代码中,箭头键对我来说很好用。 - rory.ap

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接