从类实例中获取事件处理程序

时间:2017-02-18 21:28:57

标签: vb.net

我刚刚开始使用自定义类,所以我写了一个按钮条。它继承了一个面板,并使用传递给我.Add()的字符串中的按钮填充它。

ButtonStrip1.Add("Button","Texts","Go Here")

我希望它能够自然地抓取ButtonStrip1.Click的处理程序并将其传递给子按钮并从ButtonStrip1中删除它。

我无法弄明白,所以我一直在做

Public Class ButtonStrip
    Inherits Panel
    Public Property Innermargin As Integer = 5
    Dim Offset As Integer = Innermargin
    Dim Buttons = New List(Of ButtonStrip_Button)
    Dim StoredFN As EventHandler

    Public Sub New()
    End Sub

    Function Add(fn As EventHandler, ParamArray ByVal Values As String())
        StoredFN = fn
        For Each V In Values
            Dim B As New ButtonStrip_Button
            Buttons.Add(B)
            Me.Controls.Add(B)
            B.Text = V
            B.Left = Offset + Innermargin
            B.Top = Innermargin

            Offset = B.Left + B.Width
            AddHandler B.Click, fn
        Next
        RemoveHandler Me.Click, fn
        Me.Width = Offset + Innermargin
        Me.Height = Buttons(0).height + Innermargin * 2
    End Function

    Function Add(ParamArray ByVal Values As String())
        If StoredFN Is Nothing Then
            Throw New Exception("First Add() must supply a function")
        End If
        Me.Add(StoredFN, Values)
    End Function
End Class

Public Class ButtonStrip_Button
    Inherits System.Windows.Forms.Button
    Public Sub New()
        AutoSize = True
        AutoSizeMode = AutoSizeMode.GrowAndShrink
    End Sub
End Class

调用
ButtonStrip1.Add(AddressOf ButtonStrip1_Click,"Button","Texts","Go Here")

我基本上喜欢做的是(伪代码)

Function Add(fn As EventHandler, ParamArray ByVal Values As String())
    If StoredFN is Nothing Then StoredFN = Me.Click
        ...
        AddHandler B.Click, Me.Click
    Next
    RemoveHandler Me.Click, Me.Click
    ...
End Function

我尝试过改变一些东西并且搜索了很多东西。我也尝试使用CallByName(Me,"Click",CallType.Method)CallType.Get,但我得到的错误是Expression 'Click' is not a procedure, but occurs as the target of a procedure call.它也会为未处理的事件返回完全相同的消息,例如ButtonStrip1没有{{1}事件。

我也尝试过使用MouseDown

这里没有看到将MyClass添加到.Add()的替代StoredFN

例如,此点击事件适用于我的代码

B.click

1 个答案:

答案 0 :(得分:2)

我的建议是这样的:

Public Class ButtonStrip
    Inherits Panel

    Public Event ButtonClick As EventHandler(Of ButtonClickEventArgs)

    Protected Overridable Sub OnButtonClick(e As ButtonClickEventArgs)
        RaiseEvent ButtonClick(Me, e)
    End Sub

    Private Sub Buttons_Click(sender As Object, e As EventArgs)
        OnButtonClick(New ButtonClickEventArgs(DirectCast(sender, Button)))
    End Sub

    Public Sub Add(ParamArray values As String())
        Dim btn As New Button

        AddHandler btn.Click, AddressOf Buttons_Click

        '...
    End Sub

End Class


Public Class ButtonClickEventArgs
    Inherits EventArgs

    Public ReadOnly Property Button As Button

    Public Sub New(button As Button)
        Me.Button = button
    End Sub

End Class

现在没有必要传递事件处理程序了。单击Button后,ButtonStrip会处理该事件,然后引发自己的ButtonClick事件。 ButtonStripButtons都不必关心处理该事件的任何方法,因为它将以与任何其他事件相同的方式处理。在表单中,您将处理ButtonClick的{​​{1}}事件并获取从ButtonStrip点击的Button。如果您想知道e.Button而不是Index本身的位置,也可以添加Button属性。