Wednesday, October 19, 2005 4:04 PM Christopher

How not to use the PictureBox control.

I was having this problem in an application that I've been working on where I was drawing data points onto a PictureBox control - kind of like a canvas. The problem only showed up when a lot of data was thrown at the PictureBox: instead of seeing my data, I would see a loverly big red x.

So I did some chasing down a few rabbit holes (apparently this is a difficult issue to pinpoint - I found loads of unanswered forum/newsgroup posts about a red x) and found Bob Powell's GDI+ faq. Specifically, I found a good overview of How not to use the PictureBox control. After a few trials of throwing largish datasets at my picturebox canvas (that had yeilded those nasty red x's after a few screen refreshes just minutes before) it seems like the advice in that article just may have solved the problem.

We had been drawing to a Graphics object, then using that to spit out an image to the PictureBox's .Image property:

Graphics g = pbxCanvas.CreateGraphics();

//draw to graphics

pbxCanvas.Image = GetCanvasImage();

instead, now we create the Graphics object off of the .Image in the first place. It takes a little bit more setup, but I have yet to run into the red x again since implementing this code:

if(pbxCanvas.Image == null){
	pbxCanvas.Image = new Bitmap(pbxCanvas.Width, pbxCanvas.Height);
}

Graphics g = Graphics.FromImage(pbxCanvas.Image);

//draw to graphics

pbxCanvas.Image = GetCanvasImage();
pbxCanvas.Invalidate();

Who would have thought that a call to Control.CreateGraphics would be so harmful?

Filed under: ,

Comments

# re: How not to use the PictureBox control.

Tuesday, October 25, 2005 5:17 AM by P.J. van de Sande

Why not drawing on a Bitmap and then set the pbxCanvas.Image property with the Bitmap object.

Then you don't need the CreateGraphics method from the control and you have the same result.

# re: How not to use the PictureBox control.

Tuesday, October 25, 2005 10:48 AM by Chris Frazier

Because the code that is already in place uses a Graphics object to do the drawing.

We found by doing this we could cut down on the amount of Bitmaps that were created (down to one per canvas) and redraw onto it as much as we want to.

I actually had to go back and refactor the render method because we need up to the second drawing for some of the interactive features of the canvas - so whenever we need to repaint immediately we go back to CreateGraphics, and whenever we only need to change how things are displayed via options we use the method above.

# re: How not to use the PictureBox control.

Wednesday, October 26, 2005 2:59 AM by P.J. van de Sande

Then you can use the OnPaint event, you stop using the CreateGraphics method and call Invalidate(Region) when a region or the whole Graphics is invalid.

# re: How not to use the PictureBox control.

Sunday, May 17, 2009 3:00 PM by nick_lavara

# re: How not to use the PictureBox control.

Thursday, September 22, 2011 7:25 AM by Bradley

So-so. Something was not impressed.

Leave a Comment

(required) 
(required) 
(optional)
(required)