c# - Winforms 图形闪烁。 (双缓冲没有帮助!)

标签 c# winforms visual-studio graphics double-buffering

我正在尝试创建一个简单的 Windows 窗体图形应用程序,它基本上会在每次用户单击时绘制一个圆圈,圆圈会扩大,同时慢慢消失。

当我尝试将 Paint() 事件用于我的图形功能时,没有任何反应,因此我创建了一个名为“Render”的单独函数,该函数在我的主要更新 Timer.

该应用程序运行正常,但图形闪烁。经过一些研究后,我意识到我必须启用双缓冲,这样它才能渲染到缓冲区,然后缓冲区才会渲染到屏幕。

闪烁仍然没有停止!
这是因为双缓冲仅适用于 Paint() 事件吗?如果是这样,我如何让 Paint() 事件起作用,或者我是否没有正确启用双缓冲?< br/>

这是我的代码:

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

namespace Widget
{

public class Circle
{
    public float X;
    public float Y;
    public float Radius;
    public int Alpha;

    public Circle(float X, float Y, float Radius, int Alpha)
    {
        this.X = X;
        this.Y = Y;
        this.Radius = Radius;
        this.Alpha = Alpha;
    }
}

public partial class Form1 : Form
{
    public static readonly int ScreenX = Screen.PrimaryScreen.Bounds.Width;
    public static readonly int ScreenY = Screen.PrimaryScreen.Bounds.Height;

    public int WindowWidth = 500, WindowHeight = 500;
    public Graphics G;
    private Pen Pen;

    private Timer timer = new Timer();
    private List<Circle> Circles;

    public Form1()
    {
        this.Text = "Widget - Sam Brandt";
        this.Size = new Size(WindowWidth, WindowHeight);
        this.StartPosition = FormStartPosition.Manual;
        this.Location = new Point(ScreenX - WindowWidth - 100, 0);
        this.FormBorderStyle = FormBorderStyle.FixedSingle;
        this.MaximizeBox = false;
        this.Icon = new Icon("C:\\Users\\Admin\\Desktop\\Code Repositories\\Visual Studios\\Widget\\Widget\\Properties\\WidgetIcon.ico");
        Pen = new Pen(Color.Black, 1);
        G = CreateGraphics();
        //this.Paint += new PaintEventHandler(OnPaint);
        ConstructMouse();
        FormWithTimer();
        DoubleBuffered = true;

        Circles = new List<Circle>();
    }

    public void ConstructMouse()
    {
        this.MouseUp += new MouseEventHandler(OnMouseUp);
        this.MouseMove += new MouseEventHandler(OnMouseMove);
        this.MouseDown += new MouseEventHandler(OnMouseDown);
    }

    public void FormWithTimer()
    {
        timer.Tick += new EventHandler(timer_Tick);
        timer.Interval = (10);
        timer.Enabled = true;
        timer.Start();
    }

    protected void OnMouseUp(object sender, MouseEventArgs e)
    {
    }

    protected void OnMouseMove(object sender, MouseEventArgs e)
    {
    }

    public void OnMouseDown(object sender, MouseEventArgs e)
    {
        Circles.Add(new Circle(e.Location.X, e.Location.Y, 0, 255));
    }

   /*public void OnPaint(object sender, PaintEventArgs e)
    {
        e.Graphics.Clear(Color.White);
        for (int i = 0; i < Circles.Count; i++)
        {
            Circle C = Circles[i];
            e.Graphics.DrawEllipse(new Pen(Color.FromArgb(C.Alpha, 0, 0, 0), 1), C.X - C.Radius, C.Y - C.Radius, 2 * C.Radius, 2 * C.Radius);
        }
    }*/

    private void Tick()
    {
        for (int i = 0; i < Circles.Count; i++)
        {
            Circle C = Circles[i];
            C.Radius++;
            C.Alpha -= 3;
            if (C.Alpha == 0)
            {
                Circles.RemoveAt(i);
            }
        }
    }

    public void Render()
    {
        G.Clear(Color.White);
        for (int i = 0; i < Circles.Count; i++)
        {
            Circle C = Circles[i];
            G.DrawEllipse(new Pen(Color.FromArgb(C.Alpha, 0, 0, 0), 1), C.X - C.Radius, C.Y - C.Radius, 2 * C.Radius, 2 * C.Radius);
        }
    }

    public void timer_Tick(object sender, EventArgs e)
    {
        Render();
        Tick();
    }
}
}

最佳答案

简短回答 - 保持 DoubleBuffered = true 并使用 Paint 事件。

When I tried to use a PaintEvent for my graphics functionality, nothing happened

当你做了一些修改并想反射(reflect)它们时,使用Control.Invalidate方法,根据文档

Invalidates the entire surface of the control and causes the control to be redrawn.

在你的情况下,是这样的

void timer_Tick(object sender, EventArgs e)
{
    Tick();
    Invalidate();
}

关于c# - Winforms 图形闪烁。 (双缓冲没有帮助!),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34538630/

相关文章:

c# - 以编程方式将面板的图像设置为不在资源中的 jpg 文件?

visual-studio - CMake 和缓慢的 MSVC 编译

windows - 从 Visual Studio 2013 命令提示符追加到 INCLUDE 环境变量

c# - MVC 2 DropDownList 在 List 的情况下不选择值

c# - SSRS 以编程方式设置参数导致状态 ValidValueMissing

C# 查询命令 SQL 带引号

c# - 构建代理需求的问题未针对 android 构建进行验证

c# - 以编程方式添加项目引用

c# - 一个winform来添加和更新数据

c# - 我可以在 Visual Studio 命令行参数中使用用户的环境变量吗?