Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
954 views
in Technique[技术] by (71.8m points)

.net - Which Event should I use to display drawing?

I need to put some graphics in one section of a TableLayoutPanel.

I'm doing this by creating a PictureBox in one cell of the TLP.

Can't get two things to work:

1) The initial display is blank! Drawing appears only when you resize the form

2) The resize event doesn't fire equally when expanding the size as compared contracting.

Any suggestions to improve the above two problems would be great!

Here is my code. The form has a 2x2 TableLayoutPanel in it, and one cell of the TLP has a PictureBox in it. Both the TLP and the PictureBox are set to 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

End Class

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Apparently, you are trying to draw to a picturebox (g = PictureBox1.CreateGraphics())

The reason stuff disappears is that when the size changes, or something passes over the window, the controls and form need to be repainted. This happens in the Paint event, so your code needs to do the drawing there. Unlike a PictureBox image, items drawn to a form or control are not persistent on their own, that is done by drawing in the Paint event.

This is essentially your DrawMyStuff procedure relocated to the Picbox's Paint event.

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

If you are actually trying to paint on the Form, then Grim's answer is the solution. There you respond to the Form Paint event. In either case, use the Graphics object provided by Windows as an EventArg.

Above, you are using the Graphics object for the PictureBox (via event args) so output is to the PictureBox.


Windows wont know you are drawing something in the Paint event, so you need to tell it that the image needs to be updated at certain times such as when the PictureBox is resized. In the resize event, add:

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

Me.Refresh is a bit of overkill because the entire form likely does not need to be repainted.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...