【问题标题】:One event handler for all controls on the form表单上所有控件的一个事件处理程序
【发布时间】:2011-09-14 02:15:15
【问题描述】:

我在为表单上的所有控件设置相同的事件处理程序时遇到问题。 我想在我的应用程序中统一处理按下的 f5-f7 按钮,所以我尝试为表单上的所有控件注册相同的事件处理程序。 我插入了

foreach (System.Windows.Forms.Control cont in this.Controls)
                cont.KeyDown += new System.Windows.Forms.KeyEventHandler(this.MainForm_KeyPress);

在 InitializeComponent() 函数中自动生成 ResumeLayout/PerformLayout 调用之前。别介意 MainForm_KeyPress 这个名字,它现在实际上是一个 KeyDown 事件处理程序。

我还尝试将代码插入从构造函数调用的 init() 函数中。 但结果是一样的:当我按键时,事件没有发生。焦点位于表单的一个按钮上。

但是,如果我使用设计工具实现其中一个按钮的处理程序(将函数名称复制到 KeyPress 事件字段),则如果按钮处于焦点,则事件会正确引发。

任何想法为什么 foreach 不起作用?

【问题讨论】:

  • 一个事件处理程序来统治它们?
  • 请不要在标题前加上“C#:”。这就是标签的用途。
  • @Jason - 在黑暗中数据绑定它们。
  • @Jason 是的,我想要一些特殊的按钮来统一工作。这些按钮调用设备日志捕获,并且日志是时间相关的,因此无论焦点在哪里,都必须处理这些按钮的按下事件。

标签: c# visual-studio-2010 keyboard-events


【解决方案1】:

MSDN 说您可以将 KeyPreview 设置为 true。

【讨论】:

  • 这似乎是可行的方法,您只需在表单级别注册一个事件。只需确保将 e.Handled 设置为 true 用于您实际处理的关键事件(以避免双重操作),并将所有其他事件设置为 false (否则我认为您将禁用所有其他键盘交互)。 MSDN 中的示例代码在所有情况下都将其设置为 false 的方式有点简单。
【解决方案2】:

也许您需要递归并为您遇到的每个控件的子控件注册它,在树的下方?

遇到此问题时,我要做的第一件事是将 { } 放在注册周围并输出“now registration for” + 控件名称。通过这种方式,您可以查看并查看正在注册的控件数量以及它们是什么。也许它只是主面板,子控件处理按键?在dockmanager中工作时,我也遇到了按键事件处理程序的问题,dockmanager在另一个级别处理键盘并将事件路由到它认为应该得到它的特定子控件。

如果你还是不明白,接下来我要做的就是连接表单的事件,或者甚至监控 WM_ windows 消息事件。在某些时候,WM_ 被代码转换为 .NET 事件,这可以以您意想不到的方式实现,并被第三方控件劫持等。操作系统必须将 WM_ 事件路由到您的进程,因此请使用传递事件处理程序来跟踪它们,这些处理程序会记录所发生的事情。

我完全忘记了它是如何工作的,但是当处理像按键这样的事件时,你可以返回一个布尔值或在事件上设置一个标志,表明你已经处理了它,并且在 dockmanager 实现中我看到你是否说你处理了这样,将事件传递给子控件的循环将停止,从而强制执行键盘事件应仅触发一个操作的想法。

【讨论】:

  • 我首先看到了您的回答,并按照您的建议检查是否在 foreach 中处理了所有控件。你是对的,子控件没有注册。所以我添加了一个递归,一切正常。但是 Ingenu 的答案更简单,所以我会使用它=)再次感谢您!很遗憾我不能将两个帖子标记为答案
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-03-18
  • 2013-09-17
  • 1970-01-01
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多