Reputation:
I know that double-buffering is an often-talked subject but no matter how much I searched and tried different approaches, I still can't get the control to re-draw itself without a flicker. Here's my code:
using System;
using System.Drawing;
using System.Windows.Forms;
namespace Emgu.UI
{
public class DoubleBufferedPictureBox : Control
{
const BufferedGraphics NO_MANAGED_BACK_BUFFER = null;
BufferedGraphicsContext GraphicManager;
BufferedGraphics ManagedBackBuffer;
public Bitmap Bitmap { get; set; }
public Rectangle DrawRectangle { get; set; }
public DoubleBufferedPictureBox()
{
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
GraphicManager = BufferedGraphicsManager.Current;
GraphicManager.MaximumBuffer =
new Size(Width + 1, Height + 1);
ManagedBackBuffer =
GraphicManager.Allocate(CreateGraphics(),
ClientRectangle);
Resize += DoubleBufferedPictureBox_Resize;
}
void DoubleBufferedPictureBox_Resize(object sender, EventArgs e)
{
if (ManagedBackBuffer != NO_MANAGED_BACK_BUFFER)
ManagedBackBuffer.Dispose();
GraphicManager.MaximumBuffer =
new Size(Width + 1, Height + 1);
ManagedBackBuffer =
GraphicManager.Allocate(CreateGraphics(),
ClientRectangle);
Refresh();
}
protected override void OnPaint(PaintEventArgs pe)
{
ManagedBackBuffer.Graphics.DrawImage(Bitmap, DrawRectangle);
ManagedBackBuffer.Render(pe.Graphics);
}
}
}
Any ideas?
Upvotes: 1
Views: 3406
Reputation: 28616
Are you using .Net 2.0 ? If so, I found that the following windows styles do the trick, even with old stuborn Win32 controls embeded, and it's fast too!
// Note the >>> Optimized <<< DoubleBuffer
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.UserPaint, true);
Make sure you always draw from inside a WM_PAINT message, else it will flicker. You don't need anything else, everything is automatic.
Upvotes: 2
Reputation:
Oh my God...
Like I said in my comments, the pictureBox is contained within another Control that I didn't write (but have the source to). It turns out that the flicker is caused by these two lines:
if (pictureBox.Width != _displayedImage.Width) pictureBox.Width = _displayedImage.Width;
if (pictureBox.Height != _displayedImage.Height) pictureBox.Height = _displayedImage.Height;
I think that's because the PictureBox is actually docked in the parent control...
Any way, thanks for all your responses.
Upvotes: 2
Reputation: 28699
I think the problem is in your OnPaint method, from MSDN, when you call your ManagedBackBuffer.Render method, you should pass CreateGraphics() not the Graphics property:
Upvotes: 0
Reputation: 14094
Is painting in the parent control(Form?) also double-buffered?
Your custom control may be painted without flicker but further when the parent control is painted and is not double-buffered, it's flickering.
You may be double-buffering the wrong thing.
Upvotes: 0
Reputation: 28699
Have you tried setting the controls DoubleBuffered property to true?
Upvotes: 0