不在 OnPaint() 中绘制时的双缓冲:为什么不起作用? [英] Double Buffering when not drawing in OnPaint(): why doesn't it work?

查看:27
本文介绍了不在 OnPaint() 中绘制时的双缓冲:为什么不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 C#/.Net 开发一个简单的矢量绘图应用程序.绘图是在面板中完成的,但我并没有使用 OnPaint() 事件来处理所有这些事件 - 事实上 OnPaint() 甚至只是调用了另一个方法来实际绘制文档中的所有内容.

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.

我尝试添加双缓冲,但是当我将 DoubleBuffered 设置为 true 时,闪烁问题更加严重.为什么是这样?如果我想对控件进行双缓冲,我是否绝对必须使用提供的 Graphics 对象在 OnPaint() 事件中进行所有绘图,而不是使用 Panel.CreateGraphics() 然后绘制到该对象?

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?

这是我使用的基本代码.

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);
}

总体思路是 ScaleFactor 和 Offset 两个变量指的是 UI 中的缩放级别和平移级别.g 是一个 Graphics 对象.

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.

推荐答案

g = doc.CreateGraphics();

这是错误的.双缓冲只有在您绘制到缓冲区时才能工作.e.Graphics 引用的那个.修复:

That's the mistake. Double-buffering can only work if you draw into the buffer. The one that e.Graphics references. Fix:

g = e.Graphics;

<小时>

请注意 Panel 默认没有开启双缓冲.你需要自己派生.将其粘贴到一个新类中:


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:

using System;
using System.Windows.Forms;

class BufferedPanel : Panel {
    public BufferedPanel() {
        this.DoubleBuffered = true;
        this.ResizeRedraw = true;
    }
}

编译.将其从工具箱顶部放下.

Compile. Drop it from the top of the toolbox.

这篇关于不在 OnPaint() 中绘制时的双缓冲:为什么不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆