Buffer image
I tried to implement custom double buffering, but it causes flickering.
This is the managed code (custom control that inherits from Control):
bufferContext = new BufferedGraphicsContext();
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
SetStyle(ControlStyles.DoubleBuffer, false);
SetStyle(ControlStyles.ResizeRedraw, false);
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
SetStyle(ControlStyles.Opaque, true);
OnPaint event:
protected override void OnPaint(PaintEventArgs e)
{
if (buffer == null)
{
Draw(e);
return;
}
if (Repaint)
{
Repaint = false;
PaintEventArgs pe = new PaintEventArgs(buffer.Graphics, e.ClipRectangle);
Draw(pe);
}
buffer.Render(e.Graphics);
}
Also, this code gets triggered on buffering-related resizing:
Graphics g = this.CreateGraphics();
if (buffer != null)
{
buffer.Dispose();
buffer = null;
}
if (!(bufferContext == null || DisplayRectangle.Width <= 0 || DisplayRectangle.Height <= 0))
{
buffer = bufferContext.Allocate(g, DisplayRectangle);
Repaint = true;
}
The Draw method is tricky, but it fills the control with BackColor first, it doesn't matter otherwise.
I can see with my own eyes that flickering sometimes appears, mainly when the window is resized. As I understand it, black is painted first over the control and then the graphics from the clipboard and this causes flickering. However, BackColor will never be black.
What can I do to stop this?
+3
source to share
1 answer
This example shows how to properly use buffered graphics:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace GDI_PAINTING_EXAMPLE
{
public class PaintingExample : Control
{
public Graphics G;
public Bitmap Frame = new Bitmap(256, 256);
public Bitmap Buffer = new Bitmap(256, 256);
public PaintingExample()
{
// Create a new Graphics instance.
G = Graphics.FromImage(Buffer);
}
protected override void OnPaint(PaintEventArgs e)
{
// Clears Buffer To White
G.Clear(Color.White);
//
// Do Your Painting Routine
//
//
// End Your Painting Routine
//
// Set Frame to draw as Buffer
Frame = Buffer;
// Draw Frame with Paint Event Graphics as one image.
e.Graphics.DrawImage(Frame, new Point(0, 0));
}
protected override void OnPaintBackground(PaintEventArgs pevent)
{
}
}
}
-1
source to share