Double Buffering quando non si disegna in OnPaint (): perché non funziona?

Sto lavorando a una semplice applicazione di disegno vettoriale in C # /. Net. Il disegno è fatto in un pannello, ma non sto usando l’evento OnPaint () per tutto questo, infatti OnPaint () chiama anche un altro metodo che effettivamente disegna tutto nel documento.

Ho provato ad aggiungere il doppio buffering, ma quando ho impostato DoubleBuffered su true, il problema del flicker è ancora peggiore. Perchè è questo? Se voglio raddoppiare il controllo del buffer, devo assolutamente fare tutto il mio disegno nell’evento OnPaint (), con l’object Graphics fornito, invece di usare Panel.CreateGraphics () e quindi disegnare su quello?

EDIT: questo è il codice di base che sto 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); } 

L’idea generale è che le due variabili, ScaleFactor e Offset, si riferiscono al livello di zoom e al livello di pan nell’interfaccia utente. g è un object Graphics.

 g = doc.CreateGraphics(); 

Questo è l’errore. Il doppio buffering può funzionare solo se si disegna nel buffer. Quello che fa riferimento a e.Graphics. Difficoltà:

 g = e.Graphics; 

Attenzione che il pannello non ha il doppio buffer triggersto per impostazione predefinita. Dovrai ricavarne il tuo. Incolla questo in una nuova class:

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

Compilare. Rilasciarlo dalla parte superiore della casella degli strumenti.

Personalmente non mi preoccupo delle impostazioni di DoubleBuffered. Ho appena disegnato tutto in una bitmap e poi nell’evento paint disegna quella bitmap sullo schermo.

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