我想迭代控件(例如TextBox)支持的所有事件,并以编程方式为每个事件分配相同的诊断事件处理程序。
很明显我不能使用C#+=
或VB AddHandler
命令。如何为GetType(TextBox).GetEvents()
中已知的每个事件分配事件处理程序?
Imports System.Reflection
Public Class Form1
Public Sub New()
InitializeComponent()
For Each ei As EventInfo In GetType(TextBox).GetEvents()
'AddHandler TextBox1.ei, AddressOf DiagnosticHandler - PLEASE HELP ME HERE
Next
End Sub
Private Sub DiagnosticHandler(sender As Object, e As EventArgs)
'whatever
End Sub
End Class
(C#或VB - 无论你喜欢什么。)
答案 0 :(得分:3)
EventInfo
type has AddEventHandler()
method完全是出于此目的。兼容性: .NET 3.5 及更高版本(已测试。)
最小有效代码:
Public Sub New()
InitializeComponent() ' needed only in Form class
BindHandlers(TextBox1) ' this is our binding
End Sub
Public Sub BindHandlers(c As Control)
Dim handler As MethodInfo = Me.GetType().GetMethod(NameOf(DiagnosticEventHandler))
For Each ei In c.GetType().GetEvents()
ei.AddEventHandler(c, [Delegate].CreateDelegate(ei.EventHandlerType, handler))
Next
End Sub
Public Shared Sub DiagnosticEventHandler(sender As Object, e As EventArgs)
'whatever
End Sub
注意:我只使用Public Shared
处理程序方法成功。使用Private
和非共享方法,我收到了签名兼容性错误,而我却懒得解决。
那些一直读到这一点的人的奖金:
Public Shared Sub DiagnosticEventHandler(sender As Object, e As EventArgs)
'heuristic disclosing of method related to event name
Dim maxAttempts As Integer = 15
Dim attempt As Integer = 1
Dim stackTrace As New StackTrace()
Do While attempt <= maxAttempts
Dim methodName As String = stackTrace.GetFrame(attempt).GetMethod().Name
attempt += 1
If methodName.StartsWith("On") Then
Debug.Print(String.Join(" > ", stackTrace.GetFrames().Take(attempt).Skip(1).Select(Of String)(Function(sf) sf.GetMethod.Name).Reverse().ToArray()))
Return
End If
Loop
Debug.Print(String.Join(" > ", stackTrace.GetFrames().Take(maxAttempts).Select(Of String)(Function(sf) sf.GetMethod.Name).Reverse().ToArray()))
End Sub
答案 1 :(得分:1)
以防有人需要它,这里是完成该操作的代码(假设您在表单中有一个名为textBox1的TextBox
。)
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MethodInfo miHandler = typeof(Form1).GetMethod("DiagnosticHandler", BindingFlags.NonPublic | BindingFlags.Instance);
EventInfo[] events = typeof(TextBox).GetEvents();
foreach (EventInfo ei in events)
{
Type tDelegate = ei.EventHandlerType;
Delegate d = Delegate.CreateDelegate(tDelegate, this, miHandler);
MethodInfo addHandler = ei.GetAddMethod();
Object[] addHandlerArgs = { d };
addHandler.Invoke(this.textBox1, addHandlerArgs);
}
}
private void DiagnosticHandler(object sender, EventArgs e)
{
//whatever
}
}
更多信息here