serhio
serhio

Reputation: 28586

redirect an event in VB.NET

I havea a UserControl1 (in witch I have an Label1) in Form1. I want to catch the MouseDown event from Label and send it like it was from UserControl.

I do:

Public Class UserControl1
  Shadows Custom Event MouseDown As MouseEventHandler

    AddHandler(ByVal value As MouseEventHandler)
      AddHandler Label1.MouseDown, value
    End AddHandler

    RemoveHandler(ByVal value As MouseEventHandler)
      RemoveHandler Label1.MouseDown, value
    End RemoveHandler

    RaiseEvent(ByVal sender As Object, ByVal e As MouseEventArgs)
      'RaiseMouseEvent(Me, e) ??? '
    End RaiseEvent

  End Event

End Class

However, when I set in the Form1 the UserControl

  Private Sub UserControl11_MouseDown(ByVal sender As System.Object, _ 
      ByVal e As System.Windows.Forms.MouseEventArgs) _ 
          Handles UserControl11.MouseDown

    ' here I have "Label", BUT want "UserControl" '
    MessageBox.Show(sender.GetType.Name)
  End Sub

One detail.. I want that the event should be only on the label, not on the whole userControl.

Upvotes: 2

Views: 2260

Answers (1)

Konrad Rudolph
Konrad Rudolph

Reputation: 545628

Why don’t you just handle the event “old school” and delegate it, instead of creating a custom event? Like so:

' In the user control: '
Private Sub Label1_MouseDown(sender As Object, e As MouseEventArgs) _
        Handles Label1.MouseDown
    OnMouseDown(e)
End Sub

Now when you handle the UserControl.MouseDown event in your form, the sender of the event will be the user control instance.

If you only want to capture clicks on the label (instead of on the whole user control) then you can override OnMouseDown to test from where the click originates:

Private m_MouseDownFromLabel As Boolean = False

Private Sub Label1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) _
        Handles Label1.MouseDown
    m_MouseDownFromLabel = True
    OnMouseDown(e)
End Sub

Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
    If m_MouseDownFromLabel Then
        m_MouseDownFromLabel = False
        MyBase.OnMouseDown(e)
    End If
End Sub

This should be safe in the face of race conditions since there’s only one UI thread.

By the way: RaiseMouseEvent cannot be used here since the first argument would have be the MouseDown event property. However, this property cannot be accessed from derived classes, only inside the Control class itself. I don’t know why RaiseMouseEvent isn’t private itself, instead of being protected, when it can’t be used from derived classes anyway.

Upvotes: 3

Related Questions