views:

518

answers:

3

Excuse the code dump, these are functions within a UserControl

private void PNGQuantPreviewControl_Resize(object sender, EventArgs e)
{
    createOffScreenBm();
    draw();           
} 
private void createOffScreenBm()
{
    offScreenBm = new Bitmap(this.Size.Width, this.Size.Height);
    offScreenGfx = Graphics.FromImage(offScreenBm);
}
private void draw()
{
    // draw background
    offScreenGfx.FillRectangle(transTexture, 0, 0, offScreenBm.Width, offScreenBm.Height);
    // draw image preview
    offScreenGfx.DrawImage(pngQuantPreview, getTopLeftPosition());
    // apply to picture box
    this.CreateGraphics().DrawImage(offScreenBm, 0, 0);
}

So, when the control changes size, it recreates the offscreen bitmap to reflect the new size and redraws the image.

However, if I quickly resize the control the bitmap doesn't fill it, there's a gap left at the right and/or bottom.

I'm fairly new to C#, so there's probably something obvious I'm doing wrong, or I'm reading the size values at the wrong time. Any ideas?

A: 

Do you have anything like a splitter on your control, or a MinSize or MaxSize declared?

Jonas
+1  A: 

Have you considered overriding the OnPaint method and placing the code within that method? This would result in your drawing code being executed any time the control needs to be redrawn, regardless of the reason.

A resize event does not necessarily wait until you are finished resizing the parent container. When the resize event is raised it needs to wait until the code exits before it can capture a new resize event so when the window/control is resized quickly, it can't keep up all that well and what you get is the last time it was able to capture the event, not necessarily the final state of the control ... if that makes any sense.

James Conigliaro
+1  A: 

First of all you need to overwrite OnPaint method, or subscribe to Paint event and draw everything there.

Second you do not need to create offscreen bitmap for double buffering, because in .net already exist class for such purposes BufferedGraphics.

And third, it is much better to create UserControl descedant and enable internal .net double buffering, something like this:

public UserControl2
{
    SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
}

Using this approach you will get double-buffering, and all you need is to draw your graphics in OnPaint method. You can read more about this control styles in Msdn.

arbiter
Many thanks. I used the DoubleBuffer property rather than SetStyle. Also, I didn't realise at first to use the graphics object provided as part of the OnPaint method.
Jaffa The Cake