使用C#进行双缓冲会产生负面影响

Rol*_*lig 2 c# graphics doublebuffered winforms

我编写了以下简单程序,它每100毫秒在屏幕上绘制一行(由timer1触发).我注意到绘图有点闪烁(也就是说,窗口并不总是完全是蓝色的,但是有些灰色闪耀).所以我的想法是使用双缓冲.但是当我这样做时,情况变得更糟.现在屏幕几乎总是灰色的,只是偶尔会出现蓝色(由timer2演示,DoubleBuffered每2000毫秒切换一次).

对此有什么解释?

using System;
using System.Drawing;
using System.Windows.Forms;

namespace WindowsFormsApplication1 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        private void Form1_Paint(object sender, PaintEventArgs e) {
            Graphics g = CreateGraphics();
            Pen pen = new Pen(Color.Blue, 1.0f);
            Random rnd = new Random();
            for (int i = 0; i < Height; i++)
                g.DrawLine(pen, 0, i, Width, i);
        }

        // every 100 ms
        private void timer1_Tick(object sender, EventArgs e) {
            Invalidate();
        }

        // every 2000 ms
        private void timer2_Tick(object sender, EventArgs e) {
            DoubleBuffered = !DoubleBuffered;
            this.Text = DoubleBuffered ? "yes" : "no";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Set*_*ore 5

我只是将你所有的项目都绘制到你自己的缓冲区中,然后立即将它们全部复制.我在许多应用程序中都将它用于图形处理,它对我来说一直很好用:

    public Form1()
    {
        InitializeComponent();
    }
    private void timer1_Tick(object sender, EventArgs e)
    {
        Invalidate();// every 100 ms
    }
    private void Form1_Load(object sender, EventArgs e)
    {
        DoubleBuffered = true;
    }
    private void Form1_Paint(object sender, PaintEventArgs e)
    {
        Bitmap buffer = new Bitmap(Width, Height);
        Graphics g = Graphics.FromImage(buffer);
        Pen pen = new Pen(Color.Blue, 1.0f);
        //Random rnd = new Random();
        for (int i = 0; i < Height; i++)
            g.DrawLine(pen, 0, i, Width, i);
        BackgroundImage = buffer;
    }
Run Code Online (Sandbox Code Playgroud)

编辑:经过进一步调查,看起来你的问题是你将Graphics对象设置为:

Graphics g = CreateGraphics();
Run Code Online (Sandbox Code Playgroud)

需要是:

Graphics g = e.Graphics();
Run Code Online (Sandbox Code Playgroud)

因此,您可以通过创建像我上面所做的手动缓冲区或者只是更改Graphics对象来解决您的问题.我测试了两者,它们都有效.