Reputation: 127
Sorry for my bad English.
I have a picturebox where I draw 100000 shapes (but there may be more). The drawing is made in the Paint Handler of the picturebox.
The problem is : When I Resize the form (where the picturebox is), use the scrollbar of the panel which contain it, come from another application, ... the paint handler is called... But the paint process takes quite some time and the user must wait until the paint have finished...
I tried the folowing :
NB : The size and the content of the picturebox can change, so the bitmap must also change. The creation of the bitmap + restoration of the bitmap make the application slower than before :
Bitmap bmp = new Bitmap(picturebox.Width, picturebox.Height);
// draw in Graphics.FromImage(bmp);
picturebox.Invalidate();
bmp.Dispose();
I also tried with a boolean flag : canRedraw. I set it true when the content of the picturebox change and then I call picturebox.Invalidate(). In the paint handler, I check if (canRedraw) and if so, I redraw the content (and canRedraw = false), else I make nothing. But with this last solution, when I make something with the form, my picturebox is cleared...
Do you have any idea of how I can make this :
If you are a method that change the content of the picturebox then you can redraw the picturebox, else you leave the visual content of the picturebox unchanged.
Can you help me ?
Thank you very much :)
Upvotes: 0
Views: 1612
Reputation: 54433
Besides streamlining the Paint
as dotNet suggest the other way to do it is pretty much what you tried, but you need to do it right:
Yes, do draw into a Bitmap
but not in the Paint
event, which will be called unnecessarily and then still take too much time! Instead draw only when you know that your data have changed and need to be redrawn!
You didn't tell us just what you draw but the drawing should be done like this:
void drawStuff()
{
Bitmap bmp = new Bitmap(pictureBox.ClientSize.Width, pictureBox.ClientSize.Height);
using (Graphics G = Graphics.FromImage(bmp) )
{
// do all your drawing stuff here!!
}
pictureBox.Image = bmp;
}
Call this function whenever you want the data to be drawn again!
Now you can leave the Paint
event empty, as the Image
if buffered by the System and you can still use the PictureBox.Zoom
or Image.Save
..
Upvotes: 0
Reputation: 35410
If you're not using any other functionality of the PictureBox
, try replacing it with a UserControl of your own. Then take the following steps in your UserControl:
DoubleBuffered
property of the control to True
.e.ClipRectangle
property to get the area that needs to be redrawn. Then loop through the collection of your shapes and for each shape, try to figure our whether it intersects with the ClipRectangle
. I don't know what kind of shapes you have, but there are fairly fast implementations available for most shapes, including polygon, that can check whether two polygons intersect or not. A good article about polygons intersection is available in this article, including c# code. (Note that if your shapes are rectangles, circles or triangles, the intersection problem becomes much easier and faster to compute)ClipRectangle
.Upvotes: 1