2016-08-24 1 views
0

winforms의 Graphics 클래스에 많은 경험이 없습니다. 나는 그것의 밑그림 단계에서만이다 (또한 내가 추가 한 코드). 내 문제는 패널을 만들려고합니다 : clockPanel 일부 그래픽이 포함되어 있지만 아무 예외도 발생하지만 패널 (UI에서 볼 수 있듯이)에 그래픽이 없습니다. 예제를 찾으려고 노력했지만 실수 나 내가 코드에서 찾지 못한 것을 발견 할 수 없습니다. 그래픽 사용자 경험이있는 사람들에게 쉬운 도구 일 것입니다. 시간 내 주셔서 감사합니다.클래스 인스턴스에서 Graphics를 사용하여 컨트롤 개체를 가져 오는 중

VB의 CODE : GoalsClock 클래스 인스턴스를 통해 다른 판넬 ('secondaryPannel')에 'clockpanel'패널 추가

Public Class ManagersTab 
... 
    Public Sub BuiledDashBoard() 
... 
    Dim p As GoalsClock = New GoalsClock(100, 100, 0.8) 
     p.Create() 
     p.clockPanel.Location = New Point(200, 100) 
     secondaryPannel.Controls.Add(p.clockPanel) 
... 
    End Sub 
... 
End Class 

만들기()에있어서 가장 중요한 부분이다

Class GoalsClock 

    Private Gclock As Graphics 
    Private clockWidth As Int16 
    Private clockHeight As Int16 
    Private xPos As Int16 
    Private yPos As Int16 

    Public clockPanel As Panel 
    Private panelColor As Color 

    Private PercentTextColor As Color 
    ' rectangles to store squares 
    Protected OuterRect As Rectangle 
    Protected InnerRect As Rectangle 
    Protected InnerStringBrush As Brush 
    Protected InnerStringColor As Color 
    Protected InnerStringFontSize As Byte 

    ' inner square 
    Private InnerSquarePen As Pen 
    Private InnerSquarePen_Color As Color 
    Private InnerSquarePen_Width As Byte 
    ' outer square 
    Private OuterSquarePen As Pen 
    Private OuterSquarePen_Color As Color 
    Private OuterSquarePen_Width As Byte 

    Private _PercentOfGoals As Single ' to calculate the goals deg arc 
    Public Property PercentOfGoals() As Single 
     Get 
      Return _PercentOfGoals * 100 
     End Get 
     Private Set(ByVal value As Single) 
      If value <= 1.0F Then 
       _PercentOfGoals = value 
      Else 
       value = 0 
      End If 
     End Set 
    End Property 

    Sub New(ByVal clockWidth As Int16, ByVal clockHeight As Int16, ByVal GoalsPercent As Single) 
     Me.clockWidth = clockWidth 
     Me.clockHeight = clockHeight 
     PercentOfGoals = GoalsPercent 


     ' values for test 
     xPos = 0 
     yPos = 0 
     InnerStringFontSize = 12 
     OuterSquarePen = New Pen(Color.Gray) 
     InnerSquarePen = New Pen(Color.Cyan) 
     OuterSquarePen_Width = 23 
     InnerSquarePen_Width = 15 
    End Sub 

    ''' <summary> 
    ''' 
    ''' create graphics of the goals clock on clockPanel 
    ''' </summary> 
    ''' <remarks></remarks> 
    Public Sub Create() 
     ' panel 
     clockPanel = New Panel() 
     clockPanel.Size = New Size(clockWidth, clockHeight) 
     clockPanel.BackColor = Color.Beige 
     Gclock = clockPanel.CreateGraphics() 
     ' create outer rectangle 
     OuterRect = New Rectangle(xPos, yPos, clockWidth, clockHeight) 
     ' create inner rectangle 
     Dim w, h, x, y As Integer 
     getInnerRectSizeAndLocation(w, h, x, y) 
     InnerRect = New Rectangle(x, y, w, h) 
     ' draw goals string inside inner rect 
     InnerStringBrush = Brushes.Cyan 
     Gclock.DrawString(getPercentString(), New Font("ARIAL", InnerStringFontSize, FontStyle.Bold), InnerStringBrush, InnerRect) 

     ' create outer square 
     OuterSquarePen = New Pen(OuterSquarePen_Color, OuterSquarePen_Width) 
     Gclock.DrawArc(OuterSquarePen, OuterRect, 1.0F, 360.0F) 

     ' create inner square 
     InnerSquarePen = New Pen(InnerSquarePen_Color, InnerSquarePen_Width) 
     Dim sweepAngle As Short = getSweepAngleFromGoalsPercent() 
     Gclock.DrawArc(InnerSquarePen, OuterRect, -90.0F, sweepAngle) 

    End Sub 

    Private Sub getInnerRectSizeAndLocation(ByRef w As Integer, ByRef h As Integer, ByRef x As Integer, ByRef y As Integer) 
     ' values for test 
     w = 40 
     h = 40 
     x = 64 
     y = 65 
    End Sub 

    Private Function getPercentString() As String 
     Return PercentOfGoals.ToString() & "%" 
    End Function 

    Private Function getSweepAngleFromGoalsPercent() As Single 
     ' value for test 
     Return 0.0F 
    End Function 


End Class 
+2

해당 Gclock 변수를 제거하십시오. 그래픽 객체는 절대로 저장하면 안됩니다. 그것은 제한된 수명을 의미합니다. 절대로 CreateGraphics 메서드를 사용하지 마십시오. 이러한 그래픽은 일시적이며 양식 등을 최소화하면 쉽게 지워집니다. – LarsTech

+0

@LarsTech : 우선 가장 먼저 지적했습니다. :) –

+1

다른 선원이 CreateGraphics 삼각형을 잃어 버렸습니다. Winforms 프로그래밍을 처음부터 배우는 한, WPF를 먼저 고려하십시오. 그것은 당신이 생각하는 방식과 더 잘 호환됩니다. –

답변

1

패널의 Paint event에 가입하여 모든 도면을 수행해야합니다. AddHandler statement은 이벤트를 동적으로 구독하는 데 사용됩니다.

Graphics 클래스는 그리는 것에 대한 정보를 저장하지 않으므로 패널을 다시 그릴 때 이전에 그린 모든 것이 다시 그릴 때까지 사라집니다. 여기서 Paint 이벤트가 발생합니다. 패널이 다시 그려 질 때마다 Graphics 클래스의 인스턴스를 전달하여 PaintEventArgs 클래스에 추가하므로 패널에 다시 그릴 수 있습니다. 당신은 또한 내가 지속적으로 Paint 이벤트에 새로운 Gclock 변수를 재 선언하고 본 적이 있겠지만

Public Sub Create() 
    ' panel 
    clockPanel = New Panel() 
    clockPanel.Size = New Size(clockWidth, clockHeight) 
    clockPanel.BackColor = Color.Beige 

    ' subscribe to the panel's paint event 
    AddHandler clockPanel.Paint, AddressOf clockPanel_Paint 
End Sub 

Private Sub clockPanel_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) 
    Dim Gclock As Graphics = e.Graphics 'Local variable only, as the Graphics object might change. 
    ' create outer rectangle 
    OuterRect = New Rectangle(xPos, yPos, clockWidth, clockHeight) 
    ' create inner rectangle 
    Dim w, h, x, y As Integer 
    getInnerRectSizeAndLocation(w, h, x, y) 
    InnerRect = New Rectangle(x, y, w, h) 
    ' draw goals string inside inner rect 
    InnerStringBrush = Brushes.Cyan 
    Gclock.DrawString(getPercentString(), New Font("ARIAL", InnerStringFontSize, FontStyle.Bold), InnerStringBrush, InnerRect) 

    ' create outer square 
    OuterSquarePen = New Pen(OuterSquarePen_Color, OuterSquarePen_Width) 
    Gclock.DrawArc(OuterSquarePen, OuterRect, 1.0F, 360.0F) 

    ' create inner square 
    InnerSquarePen = New Pen(InnerSquarePen_Color, InnerSquarePen_Width) 
    Dim sweepAngle As Short = getSweepAngleFromGoalsPercent() 
    Gclock.DrawArc(InnerSquarePen, OuterRect, -90.0F, sweepAngle) 
End Sub 

. 이는 패널을 그리는 데 사용되는 Graphics 인스턴스가 변경 될 수 있으므로 Paint 이벤트가 지속되는 시간보다 더 오래 저장하면 안됩니다. 따라서 클래스 상단의 선언을 제거하는 것이 좋습니다.

+0

감사합니다. "그래픽 클래스는 그리는 것에 대한 정보를 저장하지 않으므로 패널을 다시 그릴 때 이전에 그린 모든 것이 다시 그릴 때까지 사라집니다." 그래서 나는 그것을 만든 후에 그것의 작품으로 매개 변수로 Create() 메서드에 clockPannel 개체를 전달하려고 tryed. 이제는 내가 기존의 객체를 Graphics ... tnx로 전달하는 페인트 VS를 사용해야할지 결정해야합니다. – jonathana

+0

@jonathana : 당신이 정말로 컨트롤을 그려야하는 방식으로 Paint 이벤트를 사용해야합니다. LarsTech이 이미 지적했듯이'CreateGraphics()'를 사용해서는 안됩니다. –

+0

나는 이벤트를 사용할 것이다. 고맙습니다!! – jonathana

관련 문제