在不在OnPaint()中绘制时缓冲双倍:为什么不起作用?

我正在C#/ .Net中创build一个简单的vector绘图应用程序。 绘图是在一个面板中完成的,但是我没有使用OnPaint()事件 – 事实上,OnPaint()甚至只是调用另一个实际绘制文档中所有东西的方法。

我试图添加双缓冲,但是当我将DoubleBuffered设置为true时,闪烁问题更糟糕。 为什么是这样? 如果我想双重缓冲控制,我是否必须完全用OnPaint()事件绘制所提供的Graphics对象,而不是使用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(((AX + Offset.X) * ScaleFactor), ((AY + Offset.Y) * ScaleFactor)); PointF PB = new PointF(((BX + Offset.X) * ScaleFactor), ((BY + Offset.Y) * ScaleFactor)); g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; g.DrawLine(p, PA, PB); } 

一般的想法是,ScaleFactor和Offset这两个variables是指UI中的缩放级别和平移级别。 g是一个Graphics对象。

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

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

我个人不打扰DoubleBuffered设置。 我只是将所有东西绘制成位图,然后在绘画事件中在屏幕上绘制位图。

 Bitmap BackBuffer; private void MainFormSplitContainerPanel1Paint(object sender, PaintEventArgs e) { e.Graphics.Clear(MainFormSplitContainer.Panel1.BackColor); if (BackBuffer != null) e.Graphics.DrawImage(BackBuffer, positionX, positionY, SizeX, SizeY); }