在双缓冲控件上重新绘制图像而不闪烁时出现问题
我知道双缓冲是一个经常谈论的话题,但无论我如何搜索并尝试不同的方法,我仍然无法获得在不闪烁的情况下重新绘制自身的控件。 这是我的代码:
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);
}
}
}
有什么想法吗?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
天哪...
就像我在评论中所说的那样,图片框包含在我没有编写的另一个控件中(但有源代码)。 事实证明,闪烁是由这两行引起的:
我认为这是因为 PictureBox 实际上停靠在父控件中......
无论如何,感谢您的所有回复。
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:
I think that's because the PictureBox is actually docked in the parent control...
Any way, thanks for all your responses.
您使用的是.Net 2.0吗? 如果是这样,我发现以下 Windows 样式可以解决问题,即使嵌入了旧的顽固的 Win32 控件,而且速度也很快!
确保始终从 WM_PAINT 消息内部进行绘制,否则它将闪烁。
你不需要任何其他东西,一切都是自动的。
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!
Make sure you always draw from inside a WM_PAINT message, else it will flicker.
You don't need anything else, everything is automatic.
您是否尝试过设置控件DoubleBuffered 属性为true?
Have you tried setting the controls DoubleBuffered property to true?
父控件(Form?)中的绘画也是双缓冲的吗?
您的自定义控件可能会在没有闪烁的情况下绘制,但进一步当父控件被绘制并且不是双缓冲时,它会闪烁。
你可能双缓冲了错误的东西。
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.
我认为问题出在您的 OnPaint 方法中,来自 MSDN< /a>,当您调用 ManagedBackBuffer.Render 方法时,您应该传递 CreateGraphics() 而不是 Graphics 属性:
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: