设置Form.KeyPreview = true的缺点?

Dan*_*röm 25 .net windows winforms

我想知道Form.KeyPreview属性实际上有什么用处?为什么它存在以及通过将其设置为true来"冒险"?我想它必定有一些负面影响 - 否则根本不存在(或者至少默认为真)?

编辑:我非常清楚地知道什么它.我问为什么.为什么我必须将其设置为true才能使键盘事件触发?为什么键盘事件总是不会触发表单.什么不仅仅是标准行为?

我问的特殊原因是:我刚刚在我的应用程序的基本形式中设置了KeyPreview = true,其他所有形式都继承自.我是否有任何令人讨厌的惊喜?

Han*_*ant 66

Form.KeyPreview是一种不合时宜的东西,继承自Visual Basic对象模型的表单设计.回到VB6时代,您需要KeyPreview能够实现快捷键击.在Windows窗体中不再需要它,覆盖ProcessCmdKey()是更好的解决方案:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
  if (keyData == (Keys.Control | Keys.F)) {
    DoSomething();   // Implement the Ctrl+F short-cut keystroke
    return true;     // This keystroke was handled, don't pass to the control with the focus
  }
  return base.ProcessCmdKey(ref msg, keyData);
}
Run Code Online (Sandbox Code Playgroud)

但是KeyPreview支持帮助VB6程序员在2000年初转向.NET.点KeyPreview或者ProcessCmdKey()是让你的UI响应快捷键.键盘消息通常发送到具有焦点的控件.Windows窗体消息循环允许代码在控件看到之前查看该消息.这对于快捷键非常重要,KeyDown每个可能引起焦点检测的控件实现事件是非常不切实际的.

设置KeyPreview为True不会导致问题.表单的KeyDown事件将会运行,只有具有按键操作的代码才会产生影响.但要注意它紧跟VB6的使用,你无法看到用于导航的击键类型.像光标键Tab,EscapeEnter一个对话框.不是问题ProcessCmdKey().


Mic*_*han 5

来自MSDN

当此属性设置为 true 时,表单将接收所有 KeyPress、KeyDown 和 KeyUp 事件。在窗体的事件处理程序完成对击键的处理后,击键被分配给具有焦点的控件。例如,如果 KeyPreview 属性设置为 true 并且当前选定的控件是 TextBox,则在表单的事件处理程序处理击键后,TextBox 控件将接收按下的键。若要仅在窗体级别处理键盘事件并且不允许控件接收键盘事件,请将窗体的 KeyPress 事件处理程序中的 KeyPressEventArgs.Handled 属性设置为 true。

您可以使用此属性来处理应用程序中的大多数击键,并处理击键或调用适当的控件来处理击键。例如,当应用程序使用功能键时,您可能希望在表单级别处理击键,而不是为每个可能接收击键事件的控件编写代码。

基本上,当您将其设置为 true 时,您的表单可以处理关键事件以及您的控件。

EG 用户按下 K 键,调用窗体事件处理程序(Key Down、Key Up、Key Pressed),然后调用当前活动控件上的事件处理程序。

编辑:不,没有缺点或令人讨厌的惊喜。我唯一能想到的是性能下降非常小,因为它需要检查表单上每个 KeyDown、KeyUp、KeyPressed 的事件句柄。除此之外,除非您将事件处理程序添加到表单中,并做一些可能会导致问题的事情。你很好。如果您不需要全局处理除控件之外的关键事件,那么我建议您将其保留为 false 以防止额外检查。在现代 PC 上,这不会有明显的区别。