我正在c#中实现windows窗体中的搜索功能。我已经将KeyPreview
在表单上设置为true,并为KeyDown
添加了事件处理程序,因此我可以捕获ctrl+f
, esc
和enter
等内容。
我很好地抓住了这些键,我能够使我的文本框出现,但我无法在框中键入。所有的键都将指向PortsTraceForm_KeyDown(...)
,但它们永远不会进入文本框。根据msdn关于KeyPreview
的页面,将e.Handled设置为false应该会导致事件传递到焦点视图(文本框),但这并没有发生。我没有为文本框注册KeyDown
事件,所以它应该使用默认行为。我错过什么了吗?
KeyDown事件:
private void PortsTraceForm_KeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
e.Handled = false;
if (e.KeyData == (Keys.F | Keys.Control)) // ctrl+f
{
e.Handled = true;
ShowSearchBar();
}
else if (e.KeyCode == Keys.Escape) // esc
{
e.Handled = true;
HideSearchBar();
}
else if (e.KeyCode == Keys.Enter) // enter
{
if (searchPanel.Visible)
{
e.Handled = true;
if (searchShouldClear)
SearchStart();
else
SearchNext();
}
}
}
显示搜索栏:
private void ShowSearchBar()
{
FindBox.Visible = true;
FindBox.Focus(); // focus on text box
}
隐藏搜索栏:
private void HideSearchBar()
{
this.Focus(); // focus on form
FindBox.Visible = false;
}
你的文本框可能没有焦点,即使你正在调用Focus()
。来自文档:
Focus是一个低级方法,主要用于自定义控件作者。相反,应用程序程序员应该使用Select方法或ActiveControl属性来处理子控件,或者使用Activate方法来处理表单。
您可以检查Focus()
的返回值是否成功,但我在过去使用该方法将焦点设置为任意控件时运气不佳。相反,请尝试使用文档建议的方法,即调用Select()
。
没关系(尽管这仍然是有效的建议),我想我明白你的问题了:
e.SuppressKeyPress = true
你为什么要这样做?同样,从文档:
[SuppressKeyPress]获取或设置一个值,该值指示是否应将键事件传递给底层控件
所以你故意阻止TextBox获取键事件。如果你想传递事件,你不应该将该属性设置为false
。
试试这个重写方法的例子。
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
// your code here
// this is message example
MessageBox.Show(keyData.ToString());
return base.ProcessCmdKey(ref msg, keyData);
}
问候。