views:

168

answers:

1

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.

+2  A: 

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.

Konrad Rudolph
hmm. One detail.. I want that the event should be **only on the label**, not on the whole userControl
serhio
@serhio: ah. That *is* a problem. But `OnMouseDown` is `Overridable` so you can supply your own version that tests a flag to see from where the event originates. See updated answer.
Konrad Rudolph
is there a way of doing same thing with method I began?
serhio
@serhio: not using your initial approach: this simply subscribes the event handler to the label’s event directly. You can of course still use a custom event but it would have to use the same logic as in my answer above, and it would be much more code (since you have to manually manage an `EventHandler` list). What’s wrong with the second method I posted (the one with the boolean flag)?
Konrad Rudolph
nothing is wrong, is OK your method, just wondered if is possible with my method. just never worked with a EventHandlerList :)
serhio