Двойная буферизация, когда не рисуется в OnPaint (): почему это не работает? - PullRequest
8 голосов
/ 24 июня 2010

Я работаю над простым приложением векторной графики в C # /. Net.Рисование выполняется на панели, но я не использую событие OnPaint () для всех - фактически OnPaint () даже просто вызывает другой метод, который фактически рисует все в документе.

Iпопытался добавить двойную буферизацию, но когда я установил DoubleBuffered в true, проблема с мерцанием стала еще хуже.Почему это?Если я хочу удвоить буферизацию элемента управления, мне обязательно нужно выполнить все мои рисунки в событии OnPaint () с помощью предоставленного объекта Graphics вместо использования Panel.CreateGraphics () и затем рисовать в этом?

EDIT: это основной код, который я использую.

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, ссылаются на уровень масштабирования и уровень панорамирования в пользовательском интерфейсе.g является графическим объектом.

Ответы [ 2 ]

28 голосов
/ 25 июня 2010
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;
    }
}

Compile. Бросьте его из верхней части панели инструментов.

1 голос
/ 24 июня 2010

Лично я не беспокоюсь о настройке 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);
}
...