Stop raising Click Event in a specific area of a UserControl

Viewed 147

Problem

A UserControl raises by default the Click Event when a mouse button is pressed. Is there a way to prevent the event from raising when clicking on a specific area of the UserControl?

Code

Suppose that we have this specific UserControl. There is a red rectangle: I want to raise the click event only in the white area.
I've tried to override the OnMouseClick sub:

Public Class UserControl1

    Dim noClickArea As New Rectangle(100, 100, 50, 50)

    'Draw the red rectangle
    Private Sub UserControl1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
        Using gr As Graphics = Me.CreateGraphics
            gr.Clear(Color.White)
            gr.FillRectangle(Brushes.Red, noClickArea)
        End Using
    End Sub

    'This aims to prevent the mouseClick event on noClickArea
    Protected Overrides Sub OnMouseClick(e As MouseEventArgs)
        If Not noClickArea.Contains(e.Location) Then
            MyBase.OnMouseClick(e)
        End If
    End Sub

End Class

Here is a test Form that use this UserControl and show a message box on click:

Public Class Form1

    Private Sub UserControl11_Click(sender As Object, e As EventArgs) Handles UserControl11.Click
        MessageBox.Show("Click")
    End Sub
End Class

Result

Overriding OnMouseClick don't produce the expected result:

Output

How can I achieve the result I want?

1 Answers

You're overriding OnMouseClick, but you have subscribed to the Click event in your Form.
OnMouseClick is called after OnClick, so you suppress MouseClick, but the Click event has already been raised.
Override OnClick instead. Or subscribe to the MouseClick event in your Form.

Note that EventArgs of the OnClick method is actually a MouseEventArgs object, so you can cast EventArgs to MouseEventArgs:

Protected Overrides Sub OnClick(e As EventArgs)
    If Not noClickArea.Contains(CType(e, MouseEventArgs).Location) Then
        MyBase.OnClick(e)
    End If
End Sub

Then, override OnPaint instead of subscribing to the Paint event in your UserControl.
Also, do not use Me.CreateGraphics in that event or method override, it doesn't make sense.
Use the Graphics object provided by the PaintVentArgs:

Protected Overrides Sub OnPaint(e As PaintEventArgs)
    e.Graphics.Clear(Color.White)
    e.Graphics.FillRectangle(Brushes.Red, noClickArea)
    MyBase.OnPaint(e)
End Sub

As a suggestion (since I don't know what is the real use case), if you want to fill the whole Control's background with a color, set the Background Color of the Control in the Designer instead of using Graphics.Clear() in that context.

Related