Double Buffering quando não estiver desenhando no OnPaint (): por que não funciona?

Eu estou trabalhando em um aplicativo de desenho vetorial simples em c # / .net. O desenho é feito em um painel, mas eu não estou usando o evento OnPaint () para tudo isso – na verdade, o OnPaint () até mesmo chama outro método que realmente desenha tudo no documento.

Eu tentei adicionar buffer duplo, mas quando eu defino DoubleBuffered para true, o problema de flicker é ainda pior. Por que é isso? Se eu quiser duplo buffer o controle, eu absolutamente tenho que fazer todos os meus desenhos no evento OnPaint (), com o object Graphics fornecido, em vez de usar Panel.CreateGraphics () e depois desenhar para isso?

EDIT: este é o código básico que estou usando.

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

A idéia geral é que as duas variables, ScaleFactor e Offset, referem-se ao nível de zoom e ao nível de panorâmica na interface do usuário. g é um object Graphics.

 g = doc.CreateGraphics(); 

Esse é o erro. Double-buffering só pode funcionar se você desenhar no buffer. Aquele que referências e.Graphics. Consertar:

 g = e.Graphics; 

Cuidado com o fato de o Painel não ter o buffer duplo ativado por padrão. Você precisará obter o seu próprio. Cole isso em uma nova class:

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

Compilar. Solte-o da parte superior da checkbox de ferramentas.

Pessoalmente, não me incomodo com a configuração do DoubleBuffered. Acabei de desenhar tudo em um bitmap e, em seguida, no evento de pintura, desenhe esse bitmap na canvas.

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