在一个处理程序中处理所有事件?

5
在VB.NET中,是否可以轻松地编写一个事件处理程序来处理每个触发的事件?我想知道是否可以使用类似于此类的日志记录系统。
我想要做的事情是(伪代码):
Public Sub eventHandledEvent(ByVal sender As Object, ByVal e As EventArgs)
    File.Write(sender.EventName)
End Sub

我知道这会比较慢,但它仅用于开发工具,而不是生产系统。


你能提供一个代码示例来说明你想要做的吗? - Oded
3
如果你在VB中处理每一个事件,系统的速度会变得非常慢。例如,WM_PAINT 每秒会触发数千次。 - Byron Whitlock
我甚至不确定它是否可行,但在性能并不是特别重要的调试目的时可能很有用。 - davidscolgan
这应该可以通过反射来实现吧?找到所有事件,并为它们添加处理程序?有人有相关的代码吗? - MarkJ
显然没有人知道。好的,我将不得不自己回答这个问题 :) - MarkJ
2个回答

5
你可以使用reflection来完成此操作。下面是具体方法:创建一个带有名为TextBox1的文本框的表单,粘贴以下代码,运行项目并查看立即窗口。
Public Class Form1

  Private Sub Form1_Activated(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Activated
    RegisterAllEvents(TextBox1, "MyEventHandler")
  End Sub

  Sub MyEventHandler(ByVal sender As Object, ByVal e As EventArgs)
    Debug.WriteLine("An event has fired: sender= " & sender.ToString & ", e=" & e.ToString)
  End Sub
  Sub RegisterAllEvents(ByVal obj As Object, ByVal methodName As String)
    'List all events through reflection'
    For Each ei As System.Reflection.EventInfo In obj.GetType().GetEvents()
      Dim handlerType As Type = ei.EventHandlerType
      Dim method As System.Reflection.MethodInfo = Me.GetType().GetMethod(methodName)
      'Create a delegate pointing to the method'
      Dim handler As [Delegate] = [Delegate].CreateDelegate(handlerType, Me, method)
      'Register the event through reflection'
      ei.AddEventHandler(obj, handler)
    Next
  End Sub
End Class

这段内容来源于Francesco Balena的书《Programming Microsoft Visual Basic 2005 The Language》。该技术适用于任何引发事件的对象,而不仅限于控件。它使用反变性
如果你购买这本书, 就会有完整的解释和更多代码,可以让你识别哪个事件已经触发了通用处理程序,并使用正则表达式仅处理一部分事件。我觉得在此处发布如此长的摘录并不合适。

3

编辑:根据Hans的评论进行了调整。

对于一些已经内置发送消息的事件来说,这不是问题。只需要查看Control.WndProc即可。所有窗口的消息都会通过那里传递。


+1 的正确。但对于任何子控件,您必须对它们进行子类化,然后使用经过子类化的版本。例如,Public Class MyTextBox/Inherits Textbox/Overrides WndProc (code...)/end class。调用工作子程序,不要将代码放在WndProcs中。将消息和control.name传递给它。基于您关心的内容过滤消息;大多数情况下,您不会关心所有消息。 - FastAl
并不完全是这样。许多事件都没有与之相关联的窗口消息。AutoSizeChanged、BackColorChanged、BindingContextChanged等等。但这是尽可能实用的方法。 - Hans Passant
显然,这只涵盖了控件而不是所有事件。 - dr. evil
这种技术适用于具有窗口的控件,但为什么不直接使用Spy++或Winspector呢?http://www.softpedia.com/get/Security/Security-Related/Winspector.shtml 为什么要重复造轮子呢? - MarkJ

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