C# Winforms图形闪烁。(双缓冲没有帮助!)
我正在尝试创建一个简单的Windows窗体图形应用程序,它基本上会在用户每次单击并展开时画一个圆圈,同时慢慢消失。C# Winforms图形闪烁。(双缓冲没有帮助!),c#,winforms,visual-studio,graphics,double-buffering,C#,Winforms,Visual Studio,Graphics,Double Buffering,我正在尝试创建一个简单的Windows窗体图形应用程序,它基本上会在用户每次单击并展开时画一个圆圈,同时慢慢消失。 当我尝试将Paint()事件用于我的图形功能时,什么也没有发生,因此我创建了一个名为“Render”的单独函数,该函数在我的主更新计时器中调用 该应用程序运行正常,但图形闪烁。经过一些研究后,我意识到我必须启用双缓冲,以便它将渲染到缓冲区,然后将缓冲区渲染到屏幕。 闪烁的声音仍然没有停止 这是因为双缓冲仅适用于Paint()事件,如果是,如何使Paint()事件工作,还是我没有正确
当我尝试将
Paint()
事件用于我的图形功能时,什么也没有发生,因此我创建了一个名为“Render”的单独函数,该函数在我的主更新计时器中调用
该应用程序运行正常,但图形闪烁。经过一些研究后,我意识到我必须启用双缓冲,以便它将渲染到缓冲区,然后将缓冲区渲染到屏幕。
闪烁的声音仍然没有停止
这是因为双缓冲仅适用于Paint()
事件,如果是,如何使Paint()
事件工作,还是我没有正确启用双缓冲?
这是我的代码:
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();
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Threading.Tasks;
使用System.Windows.Forms;
名称空间小部件
{
公共阶级圈子
{
公共浮动X;
公众浮躁;
公众浮标半径;
公共int-Alpha;
公共圆(浮动X、浮动Y、浮动半径、整数Alpha)
{
这个.X=X;
这个。Y=Y;
这个。半径=半径;
这个α=α;
}
}
公共部分类Form1:Form
{
public static readonly int ScreenX=Screen.PrimaryScreen.Bounds.Width;
public static readonly int ScreenY=Screen.PrimaryScreen.Bounds.Height;
公共int窗宽=500,窗高=500;
公共图形G;
私人钢笔;
专用计时器=新计时器();
私人名单圈;
公共表格1()
{
this.Text=“Widget-Sam Brandt”;
this.Size=新尺寸(窗宽、窗高);
this.StartPosition=FormStartPosition.Manual;
此位置=新点(ScreenX-WindowWidth-100,0);
this.FormBorderStyle=FormBorderStyle.FixedSingle;
this.ebox=false;
this.Icon=新图标(“C:\\Users\\Admin\\Desktop\\Code Repositories\\Visual Studio\\Widget\\Widget\\Properties\\WidgetIcon.ico”);
笔=新笔(颜色:黑色,1);
G=CreateGraphics();
//this.Paint+=新的PaintEventHandler(OnPaint);
鼠标();
FormWithTimer();
双缓冲=真;
圆圈=新列表();
}
公共鼠标()
{
this.MouseUp+=新的MouseEventHandler(OnMouseUp);
this.MouseMove+=新的MouseEventHandler(OnMouseMove);
this.MouseDown+=新的MouseEventHandler(OnMouseDown);
}
public void FormWithTimer()
{
timer.Tick+=新事件处理程序(timer\u Tick);
时间间隔=(10);
timer.Enabled=true;
timer.Start();
}
MouseUp上受保护的void(对象发送器、MouseEventArgs e)
{
}
MouseMove上的受保护无效(对象发送器、MouseEventArgs e)
{
}
mousedown上的公共void(对象发送器,MouseEventArgs e)
{
添加(新的圆(e.Location.X,e.Location.Y,0,255));
}
/*public void OnPaint(对象发送器、PaintEventArgs e)
{
e、 图形。清晰(颜色。白色);
对于(int i=0;i
这里有更多的观察结果,但可能就是答案
- 为什么是计时器
- 使用Paint事件,当GDI+确定需要时调用它,您将不断地按原样使用代码进行绘制
- 您的代码使它看起来好像您没有使用双缓冲
这里有更多的观察结果,但可能会是答案
- 为什么是计时器
- 使用Paint事件,当GDI+确定需要时调用它,您将不断地按原样使用代码进行绘制
- 您的代码使它看起来好像您没有使用双缓冲
简短回答-保持
双缓冲=true
并使用绘制事件
当我尝试将PaintEvent用于图形功能时,什么也没发生
当您进行一些修改并希望反映这些修改时,请使用方法,该方法符合文档的要求
使控件的整个表面无效,并使控件重新绘制
在你的情况下,像这样的
void timer_Tick(object sender, EventArgs e)
{
Tick();
Invalidate();
}
简短回答-保持DoubleBuffered=true
并使用Paint
事件
当我尝试将PaintEvent用于图形功能时,什么也没发生
当您进行一些修改并希望反映这些修改时,请使用方法,该方法符合文档的要求
使控件的整个表面无效,并使控件重新绘制
在你的情况下,像这样的
void timer_Tick(object sender, EventArgs e)
{
Tick();
Invalidate();
}
我会把你所有的绘图都复制到一个单独的图形对象上,然后在计时器滴答声事件中将它复制到你的主图形对象上,只有在有变化的情况下。您可能需要使用布尔成员跟踪它。这意味着您的背景图形将具有