Daniel Leykauf Ответов: 3

Отражение: как привязать событие "щелчок" от одного элемента управления к другому во время выполнения.


Привет,

У меня есть contextmenustrip, и я хочу привязать каждое событие "Click" из каждого ToolStripMenuItem к другому целевому элементу управления, который также имеет событие "Click" - то есть другую кнопку.
Благодаря созданию динамического элемента управления во время выполнения (целевых кнопок) Я должен индексировать исходное событие из ToolStripMenuItem и привязать его к целевому элементу управления.

Я попробовал использовать уже Делегете.CreateDelegate (), но получил исключения target missmatch. Итак, простой рабочий образец в C# или vb.net было бы очень мило!

Спасибо вам всем!

Что я уже пробовал:

Я попробовал использовать уже Делегете.CreateDelegate (), но получил исключения target missmatch.

Mehdi Gholam

Как вы создаете свои элементы управления?
Вы можете привязать к щелчку мыши при создании элементов управления.

3 Ответов

Рейтинг:
2

#realJSOP

Когда я хочу сделать что-то подобное, я создаю метод, который выполняет желаемое действие, и вызываю его из обоих обработчиков событий. Никакого отражения или странного программирования не требуется (или не требуется).


Maciej Los

5ed!

Рейтинг:
2

Afzaal Ahmad Zeeshan

Как уже упоминалось в решении 1, Есть много других способов сделать это—самое главное, вы можете изменить общую архитектуру этого тоже, заставить их щелкнуть что-то еще, а затем инициировать функцию на других двух операциях. Это было бы гораздо проще.

В отражении, вы можете работать вокруг с EventInfo объекты, чтобы увидеть, когда что-то произошло, а затем делегировать его. У Microsoft есть только документация для этой части, которая позволяет добавить делегата к событию во время выполнения, а затем вы можете делать то, что хотите (нажмите на другую кнопку). Видеть это, Как подключить делегат, используя отражение, Майкрософт документы[^]

Главный вопрос: как бы вы вызвали событие щелчка? Так как его нет btn.Click() функция, вы лучше собираетесь использовать btn_Click обработчик событий имитировать, как если бы вы нажали на кнопку. В этом случае вам нужно будет передать параметры для этого, типичный обработчик кнопок требует,

public void btn_Click(object sender, EventArgs e) { }

Итак, вы можете сделать это с помощью,
btn_Click(secondBtn, null); // Or create an object for that 'e'!

Теперь, если вы думаете, что это некрасиво. Затем вам нужно будет использовать какой-то скрипт автоматизации пользовательского интерфейса, который сделает это за вас. Помимо этого, еще одно решение будет не легче позаботиться.

c# - получение события через отражение - переполнение стека[^]


Maciej Los

5ed!

Afzaal Ahmad Zeeshan

Спасибо, Мацей.

Рейтинг:
2

Daniel Leykauf

Привет,

Я нашел это рабочее решение на: c# - можно ли "украсть" обработчик событий из одного элемента управления и передать его другому? - переполнение стека[^]


Private Shared Sub CopyEvents(ByVal source As Object, ByVal target As Object, ParamArray events As String())
    Dim sourceType As Type = source.[GetType]()
    Dim targetType As Type = target.[GetType]()
    Dim invoker As MethodInfo = GetType(MethodAndSource).GetMethod("Invoke")
    For Each eventName As String In events
        Dim sourceEvent As EventInfo = sourceType.GetEvent(eventName)
        If sourceEvent Is Nothing Then
            Console.WriteLine("Can't find {0}.{1}", sourceType.Name, eventName)
            Continue For
        End If

        Dim raiseMethod As MethodInfo = sourceType.GetMethod("On" & sourceEvent.Name, BindingFlags.Instance Or BindingFlags.[Public] Or BindingFlags.NonPublic)
        If raiseMethod Is Nothing Then
            Console.WriteLine("Can't find {0}.On{1}", sourceType.Name, sourceEvent.Name)
            Continue For
        End If

        Dim targetEvent As EventInfo = targetType.GetEvent(sourceEvent.Name)
        If targetEvent Is Nothing Then
            Console.WriteLine("Can't find {0}.{1}", targetType.Name, sourceEvent.Name)
            Continue For
        End If

        Dim methodAndSource As MethodAndSource = New MethodAndSource(raiseMethod, source)
        Dim handler As [Delegate] = [Delegate].CreateDelegate(sourceEvent.EventHandlerType, methodAndSource, invoker)
        targetEvent.AddEventHandler(target, handler)
    Next
End Sub

Private Class MethodAndSource

    Private ReadOnly method As MethodInfo

    Private ReadOnly source As Object

    Friend Sub New(ByVal method As MethodInfo, ByVal source As Object)
        Me.method = method
        Me.source = source
    End Sub

    Public Sub Invoke(ByVal sender As Object, ByVal args As EventArgs)
        method.Invoke(source, New Object() {args})
    End Sub
End Class

' Sample call:
    CopyEvents(sourceToolTripMenu, targetControl, "Click") 


Он отлично подходит для моей цели!