在双缓冲控件上重新绘制图像而不闪烁时出现问题
我知道双缓冲是一个经常谈论的话题,但无论我如何搜索并尝试不同的方法,我仍然无法获得在不闪烁的情况下重新绘制自身的控件。 这是我的代码:
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)
痴者2024-07-20 00:09:04
您使用的是.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 消息内部进行绘制,否则它将闪烁。
你不需要任何其他东西,一切都是自动的。
就是爱搞怪2024-07-20 00:09:04
我认为问题出在您的 OnPaint 方法中,来自 MSDN< /a>,当您调用 ManagedBackBuffer.Render 方法时,您应该传递 CreateGraphics() 而不是 Graphics 属性:
~没有更多了~
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
天哪...
就像我在评论中所说的那样,图片框包含在我没有编写的另一个控件中(但有源代码)。 事实证明,闪烁是由这两行引起的:
我认为这是因为 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.