Answered by:
Use of Paint method for PictureBox

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
- Edited by IronRazerz Tuesday, February 18, 2014 8:20 PM
- Proposed as answer by Reed KimbleMVP Tuesday, February 18, 2014 8:33 PM
- Marked as answer by Franklin ChenMicrosoft employee Wednesday, February 26, 2014 10:21 AM
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
- Edited by IronRazerz Tuesday, February 18, 2014 8:20 PM
- Proposed as answer by Reed KimbleMVP Tuesday, February 18, 2014 8:33 PM
- Marked as answer by Franklin ChenMicrosoft employee Wednesday, February 26, 2014 10:21 AM
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