i've been trying to reach the following result in a winforms vb.net application
Desired Result
where each arc or circle in this image is clickable , clickable arc is colored in pink.
i managed to write the following code
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
that resulted the following output .
Output
what i didn't figure out is :
1- how to make a border for each of the arcs.
2- how to handle clicks on each of the arcs.
is there any better way than the way i'am trying to pull this off.
any help would be appreciated .
Special Thanks for Reza Aghaei for the help , i used in my solution the following code
EDIT: IMPROVED ANSWER
Disposing the graphics path , and making code neater
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
i used Reza's answer in the following stackoverflow question :
How to draw a circular progressbar pie using GraphicsPath in WinForm?
How can I treat the circle as a control after drawing it? - Moving and selecting shapes
How to drag and move shapes in C#
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With