C# WinForms 在任何类型的快速屏幕更新上闪烁



我想创建一个绘图库,以便我可以可视化一些代码(类似于Java处理(。更新绘制的会导致闪烁,我找不到修复它的方法。我正在使用绘图类和WinForms绘图。如果有另一种/更好的方法可以通过使用其他东西(Unity 除外(来实现这一点,我愿意尝试一下。

我尝试了双缓冲,但没有任何作用。无效和刷新使情况变得更糟。

编辑:它得到了修复(见评论(。我使用了在这里找到的计时器

以下是我的表单类。

Timer timer;
int i = 0;
Screen screen;
Rectangle canvas;
public Form1() {
    InitializeComponent();
    this.SetStyle(ControlStyles.UserPaint, true);
    this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
    this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    DoubleBuffered = true;
    screen = Screen.FromControl(this);
    canvas = screen.WorkingArea;
    timer = new Timer();
    timer.Interval = 10;
    timer.Tick += new EventHandler(draw);
    timer.Enabled = true;
}
public void draw(object source, EventArgs e) {
    Graphics g = CreateGraphics();
    g.FillRectangle(new SolidBrush(Color.Black), canvas);
    g.FillRectangle(new SolidBrush(Color.White), i, 0, 100, 100);
    i++;
}

不要创建图形,使用传递给 OnPaint 的图形。

在计时器上,只需计算坐标并调用 Invalidate。

using System;
using System.Drawing;
using System.Windows.Forms;
namespace Flickering
{
    public partial class Form1 : Form
    {
        Timer timer;
        Rectangle rect = new Rectangle(0, 0, 100, 100);
        Size speed = new Size(3, 1);
        Size step = new Size(3, 1);
        public Form1()
        {
            InitializeComponent();
            this.SetStyle(ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);
            timer = new Timer();
            timer.Interval = 20;
            timer.Tick += new EventHandler(Tick);
            timer.Enabled = true;
        }
        protected override void OnPaint(PaintEventArgs e)
        {
            //e.Graphics.FillRectangle(Brushes.DarkCyan, ClientRectangle);
            e.Graphics.FillRectangle(Brushes.White, rect);
        }
        public void Tick(object source, EventArgs e)
        {
            var canvas = ClientRectangle;
            step.Width = rect.Right >= canvas.Width ? -speed.Width : rect.Left < canvas.Left ? speed.Width : step.Width;
            step.Height = rect.Bottom >= canvas.Height ? -speed.Height : rect.Top < canvas.Top ? speed.Height : step.Height;
            rect.Location += step;
            Invalidate();
        }
    }
}

最新更新