【问题标题】:BufferedGraphics flickerBufferedGraphics 闪烁
【发布时间】:2013-01-27 17:34:30
【问题描述】:

我曾尝试实现自定义双缓冲,但它会导致闪烁。

这是控件(继承自控件的自定义控件)构造函数中的代码:

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 永远不会是黑色的。

如何阻止这种情况?

【问题讨论】:

  • 也覆盖 OnPaintBackground(),什么也不做。
  • 已经试过了,没用。

标签: c# winforms double-buffering


【解决方案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)
        {
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多