.net 我应该使用哪个事件显示图形?

.net 我应该使用哪个事件显示图形?,.net,vb.net,graphics,gdi+,.net,Vb.net,Graphics,Gdi+,我需要在TableLayoutPanel的一个部分中放置一些图形 我通过在TLP的一个单元格中创建一个PictureBox来实现这一点 无法让两件事起作用: 1) 初始显示为空白!图形仅在调整窗体大小时显示 2) 与收缩相比,在扩展大小时,resize事件不会均匀触发 任何改善上述两个问题的建议都是非常好的 这是我的密码。表单中有一个2x2的TableLayoutPanel,TLP的一个单元格中有一个PictureBox。TLP和PictureBox都设置为填充父对象: Imports Syst

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

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

无法让两件事起作用:

1) 初始显示为空白!图形仅在调整窗体大小时显示

2) 与收缩相比,在扩展大小时,resize事件不会均匀触发

任何改善上述两个问题的建议都是非常好的

这是我的密码。表单中有一个2x2的TableLayoutPanel,TLP的一个单元格中有一个PictureBox。TLP和PictureBox都设置为填充父对象:

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

正如汉斯·帕桑(Hans Passant)所说的那样,结束课程。首先摆脱

Private g As Graphics
以及整个
PictureBox1\u Resize(…)…
例程。然后将下面的例程更改为这样

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


。。然后测试。请回来告诉我你学到了什么!!尤其地您不需要创建新的红色画笔-所有“标准”颜色都内置-并且正确使用图形对象可以获得更好、更平滑的显示。

正如Hans Passant所说。首先摆脱

Private g As Graphics
以及整个
PictureBox1\u Resize(…)…
例程。然后将下面的例程更改为这样

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


。。然后测试。请回来告诉我你学到了什么!!尤其地您不需要创建新的红色画笔-所有“标准”颜色都内置-并且正确使用图形对象可以获得更好、更平滑的显示。

显然,您正在尝试绘制到picturebox(
g=PictureBox1.CreateGraphics()

东西消失的原因是当大小改变,或者有东西经过窗口时,控件和窗体需要重新绘制。这在绘制事件中发生,因此代码需要在那里绘制。与PictureBox图像不同,绘制到窗体或控件的项目本身不会持久化,这是通过在Paint事件中绘制完成的

这实质上是将DrawMyStuff过程重新定位到Picbox的绘制事件

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
如果你真的想在表单上画画,那么格里姆的答案就是解决方案。在这里,您可以响应表单绘制事件。在任何一种情况下,都可以使用Windows提供的
图形
对象作为事件参数

上面,您正在使用PictureBox的图形对象(通过事件args),因此输出到PictureBox


Windows不会知道您在绘制事件中绘制了什么,因此您需要告诉它,图像需要在某些时间更新,例如调整PictureBox的大小时。在“调整大小”事件中,添加:

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

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

显然,您正在尝试绘制到picturebox(
g=PictureBox1.CreateGraphics()

东西消失的原因是当大小改变,或者有东西经过窗口时,控件和窗体需要重新绘制。这在绘制事件中发生,因此代码需要在那里绘制。与PictureBox图像不同,绘制到窗体或控件的项目本身不会持久化,这是通过在Paint事件中绘制完成的

这实质上是将DrawMyStuff过程重新定位到Picbox的绘制事件

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
如果你真的想在表单上画画,那么格里姆的答案就是解决方案。在这里,您可以响应表单绘制事件。在任何一种情况下,都可以使用Windows提供的
图形
对象作为事件参数

上面,您正在使用PictureBox的图形对象(通过事件args),因此输出到PictureBox


Windows不会知道您在绘制事件中绘制了什么,因此您需要告诉它,图像需要在某些时间更新,例如调整PictureBox的大小时。在“调整大小”事件中,添加:

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

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

另一个CreateGraphics()受害者。当图片框重新绘制自身时,使用“g”绘制的任何内容都将再次被擦除。您只会意外地看到输出。必须使用PictureBox.Paint事件的事件处理程序中获得的e.Graphics对象。另一个CreateGraphics()受害者。当图片框重新绘制自身时,使用“g”绘制的任何内容都将再次被擦除。您只会意外地看到输出。您必须使用PictureBox.Paint事件的事件处理程序中获得的e.Graphics对象。。。我错过了一个事实,那就是绘画活动完全来自于形式!谢谢,非常有用。但是(见下面的评论)一个问题;为什么矩形的大小不随窗体的大小而变化?PictureBox设置为DockFill,并且TableLayoutPanel随着窗体大小的调整而调整大小,但是矩形的大小始终相同,尽管如果PictureBox为Dock.Fill,TLP为Dock.Fill,则sz为varying,如果PictureBox为Dock.Fill,则TLP为Dock.Fill为窗体,然后将
Me.Refresh()
添加到picbox Resize事件中,则应能正常工作。Windows不知道它需要重新绘制矩形,因为没有任何内容违反该区域(它不知道矩形大小取决于PB大小,因为这是您提供的)。因此,您必须强制它再次运行代码,方法是使用“刷新”命令它在大小更改时重新绘制。如果您强制它重新绘制PB(在窗体上浮动一个窗口,它会重新绘制)。您可能需要使用TLP设置才能获得所需的效果。Refresh()很好地完成了这项工作!TVMindeed@user3012629欢迎光临。格里姆的回答可能也会引导你找到答案,你应该通过向上投票两个答案来感谢他的努力。(只是一个建议)斑点很好的钚。。。我错过了一个事实,那就是绘画活动完全来自于形式!谢谢,非常有用。但是(见下面的评论)一个问题;为什么矩形的大小不随窗体的大小而变化?这个图片盒是s