覆盖派生的事件

时间:2015-05-23 18:48:59

标签: vb.net

我想"覆盖"来自派生类的事件 - 例如来自Forms-Control。

我的实际状态是,当我直接使用此控件的Handler时,覆盖(由Command" Shadows"执行)正在工作。 如果控件是Collection的成员,它只与我自己创建的这些事件一起工作 - 如果我尝试使用被覆盖的事件它不起作用。我想Collection使用Base-Class中的Event。 那可能吗 ? 如果"是" - 我能做什么 ?

来自描述"问题"的代码片段。 :

此部分收集自定义控件中的事件处理程序:

    Private KalenderElemente As New Collection

Private Sub CreateElements()

    KalenderElemente.Clear()

    For i As Integer = 1 To 42
        Dim myKalenderTag As New PP_Monatskalender_Tag
        myKalenderTag.Name = "Tag_" + i.ToString("00")
        myKalenderTag.ForeColor = my_ForeColor_Days
        myKalenderTag.BackColor = my_BackColor_Days
        myKalenderTag.Parent = Me

        AddHandler myKalenderTag.Click, AddressOf KalenderTag_Click
        AddHandler myKalenderTag.MouseMove, AddressOf KalenderTag_MouseMove
        AddHandler myKalenderTag.MouseEnter, AddressOf KalenderTag_MouseEnter
        AddHandler myKalenderTag.MouseLeave, AddressOf KalenderTag_MouseLeave

        KalenderElemente.Add(myKalenderTag)
     Next

End Sub



Private Sub Kalender_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseMove
    If Not KalenderElemente.Item(0).Visible Then
        KalenderElemente.Item(0).DatumsTag = 0
        RaiseEvent MouseMove(KalenderElemente.Item(0), e)
    Else
        KalenderElemente.Item(41).DatumsTag = 0
        RaiseEvent MouseMove(KalenderElemente.Item(41), e)
    End If
End Sub

Private Sub KalenderTag_MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
    RaiseEvent MouseMove(sender, e)
End Sub

Shadows Event MouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)

Private Sub KalenderTag_MouseEnter(ByVal sender As Object, ByVal e As EventArgs)
    RaiseEvent MouseEnter(sender, e)
End Sub

Shadows Event MouseEnter(ByVal sender As Object, ByVal e As EventArgs)

Private Sub KalenderTag_MouseLeave(ByVal sender As Object, ByVal e As EventArgs)
    RaiseEvent MouseLeave(sender, e)
End Sub

Shadows Event MouseLeave(ByVal sender As Object, ByVal e As EventArgs)

现在每个内部控件都将它的鼠标事件发送到外部。 如果我把它放在Form上并编写一个脚本来接受事件我可以看到一切正常(并且如预期的那样)。

在下文中,您将看到应该管理此Control(和其他)的集合部分:

   Public Class MessageDefinition

    Public WithEvents Control As Control
    Public HeaderText As String
    Public MessageText As String
    Public DisplayShadow As Boolean
    Public ToolTipLocation As ToolTipLocationDefintion
    Public Location As Point

End Class

Public Class Message_Collection
    Inherits CollectionBase

    Public Shadows Sub Clear()

        Dim myItem As MessageDefinition

        For i As Integer = 1 To List.Count
            myItem = List.Item(i - 1)
            RemoveHandler myItem.Control.MouseEnter, AddressOf Item_MouseEnter
            RemoveHandler myItem.Control.MouseMove, AddressOf Item_MouseMove
            RemoveHandler myItem.Control.MouseLeave, AddressOf Item_MouseLeave
        Next

        List.Clear()
    End Sub

    Overrides Function ToString() As String
        Return "[...]"
    End Function

    Public Sub Dispose()
        Clear()
    End Sub

    ' ================================

    Public Sub SetMessage(item As MessageDefinition)

        Dim myItem As MessageDefinition

        For i As Integer = 1 To List.Count
            myItem = List.Item(i - 1)
            If myItem.Control.GetType Is item.Control.GetType _
            AndAlso myItem.Control.Name = item.Control.Name Then
                'List.Item(i - 1) = item
                'RaiseEvent MouseEnter(item, System.EventArgs.Empty)
                Exit Sub
            End If
        Next

        AddHandler item.Control.MouseEnter, AddressOf Item_MouseEnter
        AddHandler item.Control.MouseMove, AddressOf Item_MouseMove
        AddHandler item.Control.MouseLeave, AddressOf Item_MouseLeave
        List.Add(item)
        RaiseEvent MouseEnter(item, System.EventArgs.Empty)
    End Sub

    Private Sub Item_MouseEnter(sender As Object, e As System.EventArgs)

        Dim myItem As MessageDefinition
        Dim mySender As Control = sender

        For i As Integer = 1 To List.Count
            myItem = List.Item(i - 1)
            If myItem.Control Is mySender Then
                RaiseEvent MouseEnter(myItem, e)
                Exit Sub
            End If
        Next

    End Sub

    Private Sub Item_MouseMove(sender As Object, e As System.EventArgs)

        Dim myItem As MessageDefinition
        Dim mySender As Control = sender

        For i As Integer = 1 To List.Count
            myItem = List.Item(i - 1)
            If myItem.Control Is mySender Then
                RaiseEvent MouseMove(myItem, e)
                Exit Sub
            End If
        Next

    End Sub

    Private Sub Item_MouseLeave(sender As Object, e As System.EventArgs)

        Dim myItem As MessageDefinition
        Dim mySender As Control = sender

        For i As Integer = 1 To List.Count
            myItem = List.Item(i - 1)
            If myItem.Control Is mySender Then
                RaiseEvent MouseLeave(myItem, e)
                Exit Sub
            End If
        Next

    End Sub

    Public Event MouseEnter(sender As Object, e As System.EventArgs)
    Public Event MouseMove(sender As Object, e As System.EventArgs)
    Public Event MouseLeave(sender As Object, e As System.EventArgs)

End Class

正如所描述的那样(在顶部),使用"标准" -Controls触发捕获的事件,但不使用"自定义"控制。

如果我更改它并构建我自己的事件(具有不同的名称),这些事件不会从派生控件中隐藏事件,它也会按预期工作。

1 个答案:

答案 0 :(得分:3)

您不会覆盖.NET中的事件 - 您只能override inherited event handlers,如果有的话。

.NET中的事件模式是在基类中创建public事件和protected virtual(VB Protected Overridable)方法,该方法引发该事件并且可以被a覆盖派生类。此方法应命名为OnEventName

Windows窗体控件遵循此模式,因此对于在Click事件发生时覆盖,您覆盖OnClick方法:

Public Class MyTextBox
    Inherits TextBox

    Protected Overrides Sub OnClick(ByVal e As System.EventArgs)
        If SomeCondition() Then
            MyBase.OnClick(e)
        Else
            Return 'Do not click
        End If
    End Sub
End Class

显然你也可以摆弄e这个论点。