I have a User Control that contains a PictureBox control.
In the User Control's load event I create a bitmap the same size as the PictureBox's ClientRectangle. I also create a Graphics to draw on the bitmap. I set the PictureBox's BackgroundImage property equal to the bitmap.
In the PictureBox's paint event I clear the bitmap, draw on it, and set the PictureBox's BackgroundImage property equal to the bitmap. Then I use e.Graphics to draw on the PictureBox's foreground. The stuff drawn on the bitmap can change each time it is redrawn.
The image that appears in the PictureBox's background is always the bitmap that existed at the beginning of the paint event. The only way I can get it to show the new image is to set BackgroundImage to Nothing before I set it to the new image. But this causes the Paint event to be constantly raised (as evidenced my Debug.Print statements at the start and end of the event handler).
I can draw my bitmap before I invalidate the PictureBox, and that may be what I have to do. But, I still want to understand what is happening here, and if there is a better way to do this.
The attached file is a simplified program showing the problem. <edited to include code inline>
In the User Control's load event I create a bitmap the same size as the PictureBox's ClientRectangle. I also create a Graphics to draw on the bitmap. I set the PictureBox's BackgroundImage property equal to the bitmap.
In the PictureBox's paint event I clear the bitmap, draw on it, and set the PictureBox's BackgroundImage property equal to the bitmap. Then I use e.Graphics to draw on the PictureBox's foreground. The stuff drawn on the bitmap can change each time it is redrawn.
The image that appears in the PictureBox's background is always the bitmap that existed at the beginning of the paint event. The only way I can get it to show the new image is to set BackgroundImage to Nothing before I set it to the new image. But this causes the Paint event to be constantly raised (as evidenced my Debug.Print statements at the start and end of the event handler).
I can draw my bitmap before I invalidate the PictureBox, and that may be what I have to do. But, I still want to understand what is happening here, and if there is a better way to do this.
The attached file is a simplified program showing the problem. <edited to include code inline>
VB.NET:
Public Class Form1
Private mgfxMyBitmap As Graphics
Private mbmpMyBitmap As Bitmap
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
MyPictureBox.Size = New Size(200, 200)
mbmpMyBitmap = New Bitmap(MyPictureBox.ClientRectangle.Width, MyPictureBox.ClientRectangle.Height)
mgfxMyBitmap = Graphics.FromImage(mbmpMyBitmap)
MyPictureBox.BackgroundImageLayout = ImageLayout.None
MyPictureBox.BackgroundImage = mbmpMyBitmap
End Sub
Private Sub MyPictureBox_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyPictureBox.Paint
Debug.Print("Paint started")
'Compose a background image on the bitmap
mgfxMyBitmap.Clear(Color.Beige)
mgfxMyBitmap.DrawEllipse(Pens.Red, 50, 50, 100, 100)
'Set the picturebox's BackgroundImage to the bitmap
MyPictureBox.BackgroundImage = Nothing 'The background image only appears if the this line is active
MyPictureBox.BackgroundImage = mbmpMyBitmap
'Draw some stuff in the picturebox's foreground
e.Graphics.DrawLine(Pens.Green, 50, 50, 100, 100)
e.Graphics.DrawLine(Pens.Purple, 150, 50, 50, 100)
Debug.Print("Paint done")
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
mgfxMyBitmap.Clear(Color.Yellow)
mgfxMyBitmap.DrawEllipse(Pens.Black, 40, 40, 60, 120)
MyPictureBox.Invalidate()
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
mgfxMyBitmap.Clear(Color.Tan)
mgfxMyBitmap.DrawRectangle(Pens.Red, 60, 60, 80, 80)
MyPictureBox.Invalidate()
End Sub
End Class
Last edited by a moderator: