мерцание буферизованной графики

Я пытался реализовать пользовательскую двойную буферизацию, но она вызывает мерцание.

Это код в конструкторе управления (настраиваемый элемент управления, наследуемый от Control):

bufferContext = new BufferedGraphicsContext();
SetStyle(ControlStyles.OptimizedDoubleBuffer, false);
SetStyle(ControlStyles.DoubleBuffer, false);
SetStyle(ControlStyles.ResizeRedraw, false);
SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint, true);
SetStyle(ControlStyles.Opaque, true);

Событие OnPaint:

protected override void OnPaint(PaintEventArgs e)
{
    if (buffer == null)
    {
        Draw(e);
        return;
    }

    if (Repaint)
    {
        Repaint = false;
        PaintEventArgs pe = new PaintEventArgs(buffer.Graphics, e.ClipRectangle);
        Draw(pe);
    }

    buffer.Render(e.Graphics);
}

Также этот код активируется при изменении размера, связанном с буферизацией:

Graphics g = this.CreateGraphics();

if (buffer != null)
{
    buffer.Dispose();
    buffer = null;
}

if (!(bufferContext == null || DisplayRectangle.Width <= 0 || DisplayRectangle.Height <= 0))
{
    buffer = bufferContext.Allocate(g, DisplayRectangle);
    Repaint = true;
}

Метод Draw сложен, но он сначала заполняет элемент BackColor, остальное не имеет значения.

Я могу заметить своими глазами, что иногда возникает мерцание, в основном при изменении размера окна. Насколько я понимаю, черный цвет закрашивается сначала над управлением, а затем над графикой из буфера, что вызывает мерцание. Однако BackColor никогда не бывает черным.

Что делать, чтобы остановить это?


person Ivan Ičin    schedule 27.01.2013    source источник
comment
Также переопределите OnPaintBackground(), ничего не делая.   -  person Hans Passant    schedule 27.01.2013
comment
Пробовал уже так, не помогло.   -  person Ivan Ičin    schedule 27.01.2013


Ответы (1)


В этом примере показано, как правильно использовать буферизованную графику:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace GDI_PAINTING_EXAMPLE
{
    public class PaintingExample : Control
    {
        public Graphics G;
        public Bitmap Frame = new Bitmap(256, 256);
        public Bitmap Buffer = new Bitmap(256, 256);

        public PaintingExample()
        {
            // Create a new Graphics instance.
            G = Graphics.FromImage(Buffer);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            // Clears Buffer To White
            G.Clear(Color.White);



            //
            // Do Your Painting Routine
            //

            //
            // End Your Painting Routine
            //



            // Set Frame to draw as Buffer
            Frame = Buffer;

            // Draw Frame with Paint Event Graphics as one image.
            e.Graphics.DrawImage(Frame, new Point(0, 0));
        }
        protected override void OnPaintBackground(PaintEventArgs pevent)
        {
        }
    }
}
person TomZee    schedule 24.08.2015