c# - 不在 OnPaint() : why doesn't it work? 中绘制时的双缓冲

标签 c# .net winforms gdi+

我正在使用 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 是一个图形对象。

最佳答案

g = doc.CreateGraphics();

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

g = e.Graphics;

请注意,默认情况下,Panel 没有启用双缓冲。你需要自己推导。将其粘贴到一个新类中:

using System;
using System.Windows.Forms;

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

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

关于c# - 不在 OnPaint() : why doesn't it work? 中绘制时的双缓冲,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3113190/

相关文章:

c# - SQL查询使用C#返回太多相同的列数据

c# - 什么是 "rooted reference"?

c# - P/Invoke Interop Assistant - 是否像导入 dll 的 header 一样简单?

.net - WPF 或 Windows 窗体

c# - 带等待的 ThreadAbortException

c# - 需要 "Dependency Properties"的简短而清晰的定义

.NET 反射/HTML 抽象?

C# - 在声明中设置初始值的缺点

wpf - ico文件和png图标文件有什么区别

c# - 如何在设计时 (C#) 隐藏一些默认控件属性?