我正在尝试编写一个聪明的小函数,它将指定的委托作为事件处理程序添加到任何动态事件的集合中的所有控件。我想要做的是将它写成一个完全通用的函数,以便我可以在各种不同的项目中使用它(可能包含在某种工具库中)。
基本上我想指定一组控件,处理事件的委托以及要处理的事件类型。我遇到的问题是我无法弄清楚如何在运行时动态指定事件。
这是我的“正在进行中的工作”子目录:
Private Sub AddHandlerToControls(controlList As ControlCollection, eventToHandle As EventHandler, eventHandlerDelegate As Func(Of Object, EventArgs), Optional filterList As List(Of Type) = {})
For Each controlInList As Control In controlList
If controlInList.HasChildren Then
AddHandlerToControls(controlInList.Controls, controlInList.MouseEnter, eventHandlerDelegate, filterList)
End If
If filterList.Count > 0 Then
If filterList.Contains(controlInList.GetType) = False Then
Continue For
End If
End If
AddHandler controlInList.MouseEnter, eventHandlerDelegate
Next
End Sub
理想情况下,我想在eventToHandle
语句的末尾使用AddHandler
参数,而不是专门使用controlInList.MouseEnter
。像这样:
AddHandler eventToHandle, eventHandlerDelegate
这样我就可以在form.load方法中动态调用这个函数,并且调用它就像我之前在sub中所做的那样,它递归地为子控件调用它自己。不知何故说“对于这个控件列表,我想将此委托用作'MouseEnter'事件处理程序”。像所以:
AddHandlerToControls(Me.Controls, control.MouseEnter, MouseEnterHandlerDelegate, new List(Of Type) {TextBox, ComboBox})
这可能只是一厢情愿的想法,我开始认为这在“通用性”这个层面上是不可能的,但这是一个有趣的问题,我认为我至少应该问。
编辑解决方案:
Private Shared Sub AddHandlerToControls(controlList As Control.ControlCollection, eventToHandle As String, eventHandlerDelegate As MethodInfo, Optional filterList As List(Of Type) = Nothing)
For Each controlInList As Control In controlList
If controlInList.HasChildren Then
AddHandlerToControls(controlInList.Controls, eventToHandle, eventHandlerDelegate, filterList)
End If
If Not filterList Is Nothing Then
If filterList.Contains(controlInList.GetType) = False Then
Continue For
End If
End If
Dim dynamicEventInfo As EventInfo = controlInList.GetType.GetEvent(eventToHandle)
Dim handlerType As Type = dynamicEventInfo.EventHandlerType
Dim eventDelegate As [Delegate] = [Delegate].CreateDelegate(handlerType, eventHandlerDelegate)
dynamicEventInfo.AddEventHandler(controlInList, eventDelegate)
Next
End Sub
我如何称呼它和使用的代表:
AddHandlerToControls(Controls, "MouseClick", GetType(MainFrm).GetMethod("MouseClickEventDelegate"), New List(Of Type) From {GetType(TextBox), GetType(ComboBox)})
Shared Sub MouseClickEventDelegate(sender As Object, eventArgs As EventArgs)
sender.SelectAll()
End Sub
这允许我在我的表单上设置所有文本框和组合框(有很多)在点击时选择所有文本,大约20行代码。最好的部分是,如果我将来添加任何内容,我将不必担心返回添加此处理程序,它将在运行时处理。它可能不是最干净的解决方案,但最终对我来说效果很好。
答案 0 :(得分:4)
两个选项:
通过lambda表达式指定“订阅委托”。我不想猜测这在VB中会是什么样子,但在C#中它会是这样的:
(control, handler) => control.MouseEnter += handler;
然后你只需要将每个控件传递给委托。
将事件名称指定为字符串,并使用反射来获取事件并订阅(Type.GetEvent
然后EventInfo.AddEventHandler
)。