我知道双缓冲是一个经常谈论的主题,但无论我搜索多少并尝试不同的方法,我仍然无法控制重新绘制自己没有闪烁。这是我的代码:
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);
}
}
}
有什么想法吗?
答案 0 :(得分:2)
天哪啊......
就像我在评论中所说的那样,pictureBox包含在另一个我没有编写的控件中(但是有源代码)。事实证明,闪烁是由这两行引起的:
if (pictureBox.Width != _displayedImage.Width) pictureBox.Width = _displayedImage.Width;
if (pictureBox.Height != _displayedImage.Height) pictureBox.Height = _displayedImage.Height;
我认为那是因为PictureBox实际上停靠在父控件中......
任何方式,感谢您的所有回复。
答案 1 :(得分:2)
您使用的是.Net 2.0吗?如果是这样的话,我发现以下的windows样式可以解决问题,即使嵌入了旧的固定Win32控件,它也很快!
// Note the >>> Optimized <<< DoubleBuffer
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.UserPaint, true);
确保始终从WM_PAINT消息中绘制,否则它将闪烁。 你不需要任何其他东西,一切都是自动的。
答案 2 :(得分:0)
您是否尝试将控件DoubleBuffered属性设置为true?
答案 3 :(得分:0)
父控件(Form?)中的绘画是否也是双缓冲的?
您的自定义控件可能会在没有闪烁的情况下进行绘制,但是当父控件被绘制并且不是双缓冲时,它会闪烁。
你可能会对错误的东西进行双重缓冲。
答案 4 :(得分:0)
我认为问题在于你的OnPaint方法from MSDN,当你调用ManagedBackBuffer.Render方法时,你应该传递CreateGraphics()而不是Graphics属性: