不在 OnPaint() 中绘图时进行双缓冲:为什么它不起作用?
我正在 C#/.Net 中开发一个简单的矢量绘图应用程序。绘图是在面板中完成的,但我没有使用 OnPaint() 事件来完成所有操作 - 事实上 OnPaint() 甚至只是调用另一个方法来实际绘制文档中的所有内容。
我尝试添加双缓冲,但是当我将 DoubleBuffered 设置为 true 时,闪烁问题更加严重。这是为什么呢?如果我想对控件进行双缓冲,我是否绝对必须使用提供的 Graphics 对象在 OnPaint() 事件中完成所有绘图,而不是使用 Panel.CreateGraphics() 然后绘图?
编辑:这是我正在使用的基本代码。
private void doc_Paint(object sender, PaintEventArgs e)
{
g = doc.CreateGraphics();
Render(ScaleFactor, Offset);
}
private void Render(float ScaleFactor, PointF offset)
{
foreach (Line X in Document.Lines) { DrawLine(X.PointA, X.PointB, X.Color, X.LineWidth); }
}
private void DrawLine(PointF A, PointF B, Color Color, float Width)
{
Pen p = new Pen(Color, Width);
PointF PA = new PointF(((A.X + Offset.X) * ScaleFactor), ((A.Y + Offset.Y) * ScaleFactor));
PointF PB = new PointF(((B.X + Offset.X) * ScaleFactor), ((B.Y + Offset.Y) * ScaleFactor));
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.DrawLine(p, PA, PB);
}
总体思路是,ScaleFactor 和 Offset 这两个变量指的是 UI 中的缩放级别和平移级别。 g 是一个 Graphics 对象。
I'm working on a simple vector drawing app in C#/.Net. The drawing is done in a panel, but I'm not using the OnPaint() event for all of it - in fact the OnPaint() even just calls another method which actually draws everything in the document.
I tried to add double buffering, but when I set DoubleBuffered to true, the flicker issue is even worse. Why is this? If I want to double buffer the control, do I absolutely have to do all my drawing in the OnPaint() event, with the supplied Graphics object, instead of using Panel.CreateGraphics() and then drawing to that?
EDIT: This is the basic code I am using.
private void doc_Paint(object sender, PaintEventArgs e)
{
g = doc.CreateGraphics();
Render(ScaleFactor, Offset);
}
private void Render(float ScaleFactor, PointF offset)
{
foreach (Line X in Document.Lines) { DrawLine(X.PointA, X.PointB, X.Color, X.LineWidth); }
}
private void DrawLine(PointF A, PointF B, Color Color, float Width)
{
Pen p = new Pen(Color, Width);
PointF PA = new PointF(((A.X + Offset.X) * ScaleFactor), ((A.Y + Offset.Y) * ScaleFactor));
PointF PB = new PointF(((B.X + Offset.X) * ScaleFactor), ((B.Y + Offset.Y) * ScaleFactor));
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
g.DrawLine(p, PA, PB);
}
The general idea is that the two variables, ScaleFactor and Offset, refer to the zoom level and pan level in the UI. g is a Graphics object.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这就是错误。仅当您绘制到缓冲区时,双缓冲才能起作用。 e.Graphics 引用的那个。修复:
请注意,Panel 默认情况下没有打开双缓冲。您需要自己派生。将其粘贴到一个新类中:
Compile。将其从工具箱顶部放下。
That's the mistake. Double-buffering can only work if you draw into the buffer. The one that e.Graphics references. Fix:
Beware that Panel doesn't have double-buffering turned on by default. You'll need to derive your own. Paste this into a new class:
Compile. Drop it from the top of the toolbox.
就我个人而言,我不关心 DoubleBuffered 设置。我只是将所有内容绘制到位图,然后在绘制事件中将该位图绘制在屏幕上。
Personally I don't bother with the DoubleBuffered setting. I just draw everything to a bitmap and then in the paint event draw that bitmap on the screen.