Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Double buffering with Panel

Double buffering the whole form can be done by setting the value of the "AllPaintingInWmPaint", "UserPaint" and "DoubleBuffer" ControlStyles to "true" (this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true)).

But this can't happen with a System.Windows.Forms.Panel because the class doesn't allow me to do so. I have found one solution: http://bytes.com/topic/c-sharp/answers/267635-double-buffering-panel-control . I have also tried this: Winforms Double Buffering . It's laggy, even when it's used on a small drawing, I have some custom resources that I'm using in the form and other things because of which I won't turn the whole form into one drawing. And the second one seems to cause problems. Are there other ways to do that?

I'm asking this because I don't want the drawing on the panel to flash all the time when the form is being resized. If there is a way to get rid of the flashing without double buffering, I'll be happy to know.

like image 604
AlexSavAlexandrov Avatar asked Dec 09 '22 05:12

AlexSavAlexandrov


2 Answers

Use a PictureBox if you don't need scrolling support, it is double-buffered by default. Getting a double-buffered scrollable panel is easy enough:

using System;
using System.Windows.Forms;

class MyPanel : Panel {
    public MyPanel() {
        this.DoubleBuffered = true;
        this.ResizeRedraw = true;
    }
}

The ResizeRedraw assignment suppresses a painting optimization for container controls. You'll need this if you do any painting in the panel. Without it, the painting smears when you resize the panel.

Double-buffering actually makes painting slower. Which can have an effect on controls that are drawn later. The hole they leave before being filled may be visible for a while, also perceived as flicker. You'll find counter-measures against the effect in this answer.

like image 140
Hans Passant Avatar answered Dec 26 '22 20:12

Hans Passant


I should have posted my solution a long time ago...

Well, here is my solution:

Bitmap buffer = new Bitmap(screenWidth, screenHeight);//set the size of the image
System.Drawing.Graphics gfx = Graphics.FromImage(buffer);//set the graphics to draw on the image
drawStuffWithGraphicsObject(gfx);//draw
pictureBox1.Image = buffer;//set the PictureBox's image to be the buffer

Makes me feel like a complete idiot for finding this solution years after asking this question.

I have tried this with a Panel, but it has proven to be slower when applying the new image. Somewhere I had read, that it is better to use Panel instead of PictureBox. I don't know if I have to add something to the code to speed things up for the Panel, though.

like image 45
AlexSavAlexandrov Avatar answered Dec 26 '22 21:12

AlexSavAlexandrov