Я пытаюсь написать умную небольшую функцию здесь, которая добавит указанный делегат в качестве обработчика событий ко всем элементам управления в коллекции для любого динамического события. То, что я пытаюсь сделать, это написать это как полностью общую функцию, чтобы я мог использовать ее в различных проектах (возможно, в том числе и в какой-то библиотеке инструментов).Можно ли динамически указывать тип события при использовании AddHandler?
В основном я хочу указать группу элементов управления, делегат для обработки события и тип события для обработки. Проблема, с которой я сталкиваюсь, заключается в том, что я не могу понять, как динамически указывать событие во время выполнения.
Вот моя «работа в прогрессе» к югу:
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, и называют это вроде как я делал раньше в суб, где она рекурсивно, называющая себя для дочерних элементов управления. Как-то сказать «для этого списка элементов управления я хотел бы использовать этот делегат в качестве обработчика событий« MouseEnter ». Как так:
AddHandlerToControls(Me.Controls, control.MouseEnter, MouseEnterHandlerDelegate, new List(Of Type) {TextBox, ComboBox})
Это может быть просто wishfull мышление, я начинаю думать, что это не вполне возможно на этом уровне «родовой», но это достаточно интересная проблема, что я думал, что я должен в наименее спросите.
Edit для решения: предложение
Джона Скита использования Reflection в конечном итоге работает для меня. Вот последняя функция:
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 строках кода. Самое приятное то, что если я добавлю в будущем, мне не придется беспокоиться о возврате, чтобы добавить этого обработчика, во время выполнения его позаботятся. Это может быть не самое чистое решение, но в итоге он отлично работает для меня.
Вы можете попробовать что-то через отражение на линиях этой ссылки: http: // stackoverflow.ком/вопросы/2802774/трассировка-все-события-в-Vb-сеть. Но я думаю, что вы не можете дать вид стандартного лечения, которое вы ищете для всех событий со всех элементов управления. – varocarbas
Ну ... Если Джон Скит говорит, что это возможно, я думаю, что нет никаких сомнений. Если вам не ясно, ответ в приведенной выше ссылке содержит рабочий код VB.NET для второго варианта, который он предлагает. – varocarbas