locked
Use of Paint method for PictureBox RRS feed

  • Question

  • I have a program that paints some objects using Graphics into the PaintBox.   It works well.  I call it only after a large simulation calculation is complete. 

    However, when I cover the paintbox with another window and then reveal it, the image is gone.  

    So I placed the painting code into the Paint handler, as well.  Now it paints again and again in a ferocious loop. 

    It would take a lot of work to rewrite it, but  is the correct method to...

    -> Place all the graphics code in the Paint method, and somehow trigger a call to this paint method when the calculation is complete?

    The graphics are rather complex and should not be called frequently.

    Tuesday, February 18, 2014 7:38 PM

Answers

  • Hi,

     I would draw the graphics to a Bitmap and then draw the bitmap image in the paint event or assign the bitmap to the picturebox image property and don`t even use the paint event.

    EDIT : Here is an example of drawing to a bitmap and assigning it to the picturebox image property.

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Using bm As New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height)
    
                Using grx As Graphics = Graphics.FromImage(bm)
                    grx.DrawRectangle(Pens.Blue, 10, 10, 100, 100)
                    grx.FillEllipse(Brushes.Red, 50, 50, 20, 100)
                End Using
    
                If PictureBox1.Image IsNot Nothing Then PictureBox1.Image.Dispose()
                PictureBox1.Image = New Bitmap(bm)
            End Using
        End Sub
    

    Tuesday, February 18, 2014 7:50 PM

All replies

  • Hi,

     I would draw the graphics to a Bitmap and then draw the bitmap image in the paint event or assign the bitmap to the picturebox image property and don`t even use the paint event.

    EDIT : Here is an example of drawing to a bitmap and assigning it to the picturebox image property.

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Using bm As New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height)
    
                Using grx As Graphics = Graphics.FromImage(bm)
                    grx.DrawRectangle(Pens.Blue, 10, 10, 100, 100)
                    grx.FillEllipse(Brushes.Red, 50, 50, 20, 100)
                End Using
    
                If PictureBox1.Image IsNot Nothing Then PictureBox1.Image.Dispose()
                PictureBox1.Image = New Bitmap(bm)
            End Using
        End Sub
    

    Tuesday, February 18, 2014 7:50 PM
  • Using a buffer image is the answer, whether you want to draw it to the form directly or display it in a PictureBox or as the BackgroundImage of a control.

    Just be sure that you do not create a new image every time you redraw if you don't need to; just keep one image instance and draw over it as required.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Tuesday, February 18, 2014 8:36 PM
  • Hi,

     I would draw the graphics to a Bitmap and then draw the bitmap image in the paint event or assign the bitmap to the picturebox image property and don`t even use the paint event.

    EDIT : Here is an example of drawing to a bitmap and assigning it to the picturebox image property.

        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Using bm As New Bitmap(PictureBox1.ClientSize.Width, PictureBox1.ClientSize.Height)
    
                Using grx As Graphics = Graphics.FromImage(bm)
                    grx.DrawRectangle(Pens.Blue, 10, 10, 100, 100)
                    grx.FillEllipse(Brushes.Red, 50, 50, 20, 100)
                End Using
    
                If PictureBox1.Image IsNot Nothing Then PictureBox1.Image.Dispose()
                PictureBox1.Image = New Bitmap(bm)
            End Using
        End Sub

    I agree with Razerz. However if you resize the form the bitmap may loose quality etc. So you need to consider that verses how long it takes to draw. You can run quite a few lines of drawing code in the paint event. If your drawing routine takes more than a say 1/4 second or so on target computer then the bitmap will probably be best. Otherwise there is nothing wrong with drawing in the paint event. Or calling a subroutine from there that does the drawing. Unless there is some other unkown of course. Or you can picturebox1.refresh to fire the paint event from somewhere else.

    Tuesday, February 18, 2014 8:40 PM
  • I have a program that paints some objects using Graphics into the PaintBox.   It works well.  I call it only after a large simulation calculation is complete. 

    However, when I cover the paintbox with another window and then reveal it, the image is gone.  

    So I placed the painting code into the Paint handler, as well.  Now it paints again and again in a ferocious loop. 

    It would take a lot of work to rewrite it, but  is the correct method to...

    -> Place all the graphics code in the Paint method, and somehow trigger a call to this paint method when the calculation is complete?

    The graphics are rather complex and should not be called frequently.

    Maybe something that uses this type of functionality?

    Option Strict On
    
    Public Class Form1
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.CenterToScreen()
            PictureBox1.BackColor = Color.White
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            If PaintIt = False Then
                OneInteger = 120
                SecondInteger = 85
                PaintIt = True
                PictureBox1.Refresh()' Makes painting display
            Else
                PaintIt = False
                OneInteger = 10
                SecondInteger = 10
                PictureBox1.Refresh() ' Removes painting
            End If
        End Sub
    
        Dim PaintIt As Boolean = False
        Dim OneInteger As Integer = 10
        Dim SecondInteger As Integer = 10
    
        Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
            e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.AntiAlias
            If PaintIt = True Then
                Using Brush1 As New SolidBrush(Color.Aqua)
                    Dim Pen1 As New Pen(Brush1, 20)
                    e.Graphics.FillEllipse(Brushes.Yellow, 10, 10, OneInteger, SecondInteger)
                    e.Graphics.DrawEllipse(Pens.Aqua, 10, 10, OneInteger, SecondInteger)
                End Using
            End If
        End Sub
    
    End Class


    Please BEWARE that I have NO EXPERIENCE and NO EXPERTISE and probably onset of DEMENTIA which may affect my answers! Also, I've been told by an expert, that when you post an image it clutters up the thread and mysteriously, over time, the link to the image will somehow become "unstable" or something to that effect. :) I can only surmise that is due to Global Warming of the threads.


    • Edited by Mr. Monkeyboy Wednesday, February 19, 2014 2:52 AM 5555
    Wednesday, February 19, 2014 2:51 AM