2016-11-05 2 views
3

я пытался достичь следующего результата в приложении WinForms vb.netКак обрабатывать событие нажмите на формы System.Drawing

Desired Result

где каждая дуга или окружность в этом изображении кликабельна , clickable arc окрашен в розовый цвет.

я успел написать следующий код

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- как обрабатывать клики по каждой из дуг.

есть ли лучший способ, чем я пытаюсь это сделать.

любая помощь будет оценена.

+0

Они Арент объекты так, чтобы они не будут иметь события щелчка. Вы можете удержать прямоугольники, чтобы увидеть, находится ли мышь внутри одного или другого при нажатии, но будут проблемы с ними как дуги – Plutonix

+0

@Plutonix, что вам порекомендовать для сохранения нужного результата? –

+0

@RezaAghaei, вы хотите сказать, что я могу использовать rectangle.contains? можете ли вы предоставить пример короткого кода, чтобы все было ясно? –

ответ

2

Отдельное спасибо за Реза Aghaei за помощь, я использовал в своем решении следующий код

EDIT: ПОВЫШЕНИЕ ОТВЕТ

Располагая графический путь, и сделать код аккуратнее

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 

Я использовал ответ Резы в следующем вопросе stackoverflow:

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#

+1

Кстати, ответ имеет утечку памяти. Вы создаете какой-то «GraphicsPath» в событии рисования снова и снова. –

+1

Вы должны создать их только один раз. Если вы создаете их снова и снова, не удаляя их, вы получите некоторые исключения и даже столкнетесь с некоторыми проблемами при создании дескрипторов Windows. Вы должны решить проблему! –

+0

Я объявлял графический путь на уровне класса, чтобы использовать его в событии click, могу ли я очистить его вместо утилизации? –

Смежные вопросы