我应该使用哪个事件来显示绘图?

时间:2014-07-24 08:36:15

标签: .net vb.net graphics gdi+

我需要将一些图形放在TableLayoutPanel的一个部分中。

我是通过在TLP的一个单元格中创建PictureBox来实现的。

无法完成两件事:

1)初始显示为空白!只有在调整表单

时才会显示绘图

2)在比较合同时,扩大尺寸时,调整大小事件不会同等。

任何改善上述两个问题的建议都会很棒!

这是我的代码。表单中有一个2x2的TableLayoutPanel,TLP的一个单元格中有一个PictureBox。 TLP和PictureBox都设置为Fill Parent:

Imports System.Drawing.Drawing2D

Public Class Form1
    Private g As Graphics
    Dim n As Integer = 0

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    Debug.Print(String.Format("{0}{0}Form1_Load at {1}", vbCrLf, Now()))
    Me.SetDesktopLocation(800, 200)
End Sub

Private Sub Form1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
    n += 1
    Debug.Print(String.Format("MyBase.Paint: {0}", n))
    DisplayMyStuff()
End Sub

Private Sub PictureBox1_Resize(sender As Object, e As EventArgs) Handles Pict    ureBox1.Resize
    n += 1
    Debug.Print(String.Format("PictureBox1.Resize: {0}  PictureBoxSize = {1} / {2}", n, PictureBox1.Width, PictureBox1.Height))
    If g IsNot Nothing Then
        g.Dispose()
    End If
    g = PictureBox1.CreateGraphics()
End Sub

Private Sub DisplayMyStuff()
    Dim rect1 As Rectangle
    Dim rect2 As Rectangle
    Dim pt1 As New Point(50, 50)
    Dim pt2 As New Point(100, 100)
    Dim pt3 As New Point(150, 150)
    Dim brR As New SolidBrush(Color.Red)
    Dim linGradBr As New LinearGradientBrush(pt2, pt3, Color.Yellow, Color.Blue)
    Dim pictBoxSize As Size
    Dim sz As Size
    Dim width, height As Integer

    pictBoxSize = New Size(CType(PictureBox1.Size, Point))
    width = CInt(pictBoxSize.Width / 2)
    height = CInt(pictBoxSize.Height / 2)
    sz = New Size(width, height)
    n += 1
    Debug.Print(String.Format("DisplayMyStuff: {0}, Half-Size = {1} / {2}", n, width, height))
    g.Clear(Color.Bisque)
    rect1 = New Rectangle(pt1, sz)
    rect2 = New Rectangle(pt2, sz)
    g.FillRectangle(brR, rect1)
    g.FillRectangle(linGradBr, rect2)
    brR.Dispose()
    linGradBr.Dispose()
End Sub

结束班

2 个答案:

答案 0 :(得分:2)

显然,您正试图绘制到图片框(g = PictureBox1.CreateGraphics()

原因消失的原因是当大小改变或者某些东西经过窗口时,控件和表单需要重新绘制。这发生在Paint事件中,因此您的代码需要在那里进行绘制。与PictureBox图像不同,绘制到窗体或控件的项目不是自己持久的,这可以通过绘制Paint事件来完成。

这基本上是你的DrawMyStuff程序重新定位到Picbox的Paint事件。

Private Sub PictureBox1_Paint(sender As Object, 
          e As PaintEventArgs) Handles PictureBox1.Paint
    Dim pt1 As New Point(50, 50)
    Dim pt2 As New Point(100, 100)
    Dim pt3 As New Point(150, 150)

    Dim sz As New Size(CInt(PictureBox1.Size.Width / 2),
                       CInt(PictureBox1.Size.Height / 2))
    n += 1
    Debug.Print(String.Format("DisplayMyStuff: {0}, 
            Half-Size = {1} / {2}", n, sz.Width, sz.Height))

    Dim rect1 As New Rectangle(New Point(50, 50), sz)
    Dim rect2 As New Rectangle(New Point(100, 100), sz)

    Using linGradBr As New LinearGradientBrush(pt2, pt3, Color.Yellow, Color.Blue)

        e.Graphics.Clear(Color.Bisque)

        e.Graphics.DrawRectangle(Pens.Black, rect1)
        e.Graphics.DrawRectangle(Pens.Black, rect2)

        e.Graphics.FillRectangle(Brushes.Red, rect1)
        e.Graphics.FillRectangle(linGradBr, rect2)

    End Using
End Sub

如果你真的想在表格上画画,那么Grim的答案就是解决方案。在那里你回应Form Paint事件。在任何一种情况下,请使用Windows提供的Graphics对象作为EventArg。

上面,您正在使用PictureBox的Graphics对象(通过事件参数),因此输出到PictureBox。


Windows不会知道你在Paint事件中绘制了一些东西,所以你需要告诉它需要在某些时候更新图像,例如调整PictureBox的大小。在resize事件中,添加:

PictureBox1.Invalidate       ' tell windows it needs to be redrawn
' or
PictureBox1.Refresh          ' redraw now

Me.Refresh有点矫枉过正,因为整个表单可能不需要重新绘制。

答案 1 :(得分:1)

正如Hans Passant所说。首先摆脱;

Private g As Graphics

和整个PictureBox1_Resize(...)...例行程序。然后将以下例程更改为如此;

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

Private Sub DisplayMyStuff(pGraphics As Graphics)
    Dim pt1 As New Point(50, 50)
    Dim pt2 As New Point(100, 100)
    Dim pt3 As New Point(150, 150)
    Dim pictBoxSize As New Size(CType(PictureBox1.Size, Point))
    Dim width As Integer = CInt(pictBoxSize.Width / 2)
    Dim height As Integer = CInt(pictBoxSize.Height / 2)
    Dim sz As New Size(width, height)

    pGraphics.Clear(Color.Bisque)

    Dim rect1 As New Rectangle(pt1, sz)
    Dim rect2 As New Rectangle(pt2, sz)
    Using linGradBr As New LinearGradientBrush(pt2, pt3, Color.Yellow, Color.Blue)
        pGraphics.FillRectangle(Brushes.Red, rect1)
        pGraphics.FillRectangle(linGradBr, rect2)
    End Using
End Sub

..然后测试。请回复告诉我你已经学到了什么!!特别是..你不需要创造一个新的红色画笔 - 所有标准'颜色是内置的 - 并且使用图形对象正确地导致更好,更平滑的显示。