如何处理 System.Drawing 形状的点击事件

How to handle click event on shapes of System.Drawing

我一直在尝试在 winforms vb.net 应用程序中达到以下结果

Desired Result

这张图片中的每个圆弧或圆都是可点击的, 可点击弧线为粉红色。

我写出了下面的代码

Private Sub Form1_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint

    'Create pen objects 
    Dim p As New Pen(Color.Green, 30)
    Dim p1 As New Pen(Color.Yellow, 30)
    Dim p2 As New Pen(Color.Red, 30)
    Dim p3 As New Pen(Color.Blue, 30)

    'Create rectangle objects 
    Dim rt As New Rectangle(160, 150, 80, 100)
    Dim rt1 As New Rectangle(100, 150, 80, 100)
    Dim rt2 As New Rectangle(130, 120, 80, 100)
    Dim rt3 As New Rectangle(130, 180, 80, 100)

    'Draw arcs 
    e.Graphics.DrawArc(p, rt, 45, -90)
    e.Graphics.DrawArc(p1, rt1, -135, -90)
    e.Graphics.DrawArc(p2, rt2, -45, -90)
    e.Graphics.DrawArc(p3, rt3, 135, -90)

End Sub

导致以下输出。

Output

我没弄明白的是:

1-如何为每个弧线制作边框。

2- 如何处理每个圆弧上的点击。

有没有比我尝试的方法更好的方法。

如有任何帮助,我们将不胜感激。

特别感谢 Reza Aghaei 的帮助, 我在我的解决方案中使用了以下代码

编辑:改进答案

配置图形路径,让代码更整洁

Imports System.Drawing.Drawing2D
Public Class SurfaceSelection

Private Sub SurfaceSelection_Click(sender As Object, e As MouseEventArgs) Handles Me.Click
    Dim hitSurface As String = String.Empty
    If GetPath(EnumsClass.SurfacesEnum.L).IsVisible(e.Location) Then
        hitSurface = "L"
    ElseIf GetPath(EnumsClass.SurfacesEnum.M).IsVisible(e.Location) Then
        hitSurface = "M"
    ElseIf GetPath(EnumsClass.SurfacesEnum.F).IsVisible(e.Location) Then
        hitSurface = "F"
    ElseIf GetPath(EnumsClass.SurfacesEnum.D).IsVisible(e.Location) Then
        hitSurface = "D"
    Else
        hitSurface = "Missed"
    End If

    MsgBox(hitSurface)

End Sub

Private Sub SurfaceSelection_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint

    Me.DrawPath(EnumsClass.SurfacesEnum.L, e)
    Me.DrawPath(EnumsClass.SurfacesEnum.M, e)
    Me.DrawPath(EnumsClass.SurfacesEnum.F, e)
    Me.DrawPath(EnumsClass.SurfacesEnum.D, e)

End Sub

Private Sub DrawPath(ByVal v_bytSurface As EnumsClass.SurfacesEnum, ByVal e As System.Windows.Forms.PaintEventArgs)
    Using p As GraphicsPath = GetPath(v_bytSurface)
        e.Graphics.FillPath(Brushes.Green, p)
        e.Graphics.DrawPath(Pens.Black, p)
    End Using
End Sub

Private Function GetPath(ByVal v_bytSurface As EnumsClass.SurfacesEnum) As GraphicsPath
    Dim path As New GraphicsPath
    Dim center = New Point(100, 100)
    Dim innerR = 70
    Dim thickness = 20
    Dim startAngle = getGraphicsPathAngle(v_bytSurface)
    Dim arcLength = 70
    Dim outerR = innerR + thickness
    Dim outerRect = New Rectangle(center.X - outerR, center.Y - outerR, 2 * outerR, 2 * outerR)
    Dim innerRect = New Rectangle(center.X - innerR, center.Y - innerR, 2 * innerR, 2 * innerR)
    path.AddArc(outerRect, startAngle, arcLength)
    path.AddArc(innerRect, startAngle + arcLength, -arcLength)
    path.CloseFigure()
    Return path
End Function

Private Function getGraphicsPathAngle(ByVal v_bytSurface As EnumsClass.SurfacesEnum) As Integer
    Select Case v_bytSurface
        Case EnumsClass.SurfacesEnum.F
            Return 235
        Case EnumsClass.SurfacesEnum.O
            Return 0
        Case EnumsClass.SurfacesEnum.L
            Return 55
        Case EnumsClass.SurfacesEnum.M
            Return 145
        Case EnumsClass.SurfacesEnum.D
            Return 325
        Case EnumsClass.SurfacesEnum.Unspecified
            Return -1

    End Select

End Function

End Class

Public Class EnumsClass
    Public Enum SurfacesEnum As Byte
        Unspecified = 0
        F = 1
        O = 2
        L = 3
        M = 4
        D = 5
    End Enum
End Class

我在以下 Whosebug 问题中使用了 Reza 的回答: