使用面板绘制事件时图形闪烁
Graphics flickering when using Panel paint event
我创建了一个可以根据实时时间正常工作的模拟时钟。
我不希望你为我解决这个问题或其他任何事情 - 我的代码已经可以工作了,但它闪烁得很厉害,而且由于我的知识有限,我无法确定我需要更改的到底是什么停止闪烁。
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 ClockAndStuff
{
public partial class TheName : Form
{
public TheName()
{
InitializeComponent();
timer1.Start();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
Graphics surfaceBckg;
Graphics surfaceMin;
Graphics surfaceH;
Graphics surfaceSec;
Pen penMin = new Pen(Color.Pink,2);
Pen penH = new Pen(Color.Red,3);
Pen penSec = new Pen(Color.DeepPink,1);
Pen black = new Pen(Color.Black, 4F);
surfaceBckg = panel1.CreateGraphics();
surfaceBckg.TranslateTransform(250, 250);
surfaceBckg.DrawEllipse(black,-220,-220,440,440);
surfaceMin = panel1.CreateGraphics();
surfaceMin.TranslateTransform(250, 250);
surfaceMin.RotateTransform(6 * DateTime.Now.Minute);
surfaceH = panel1.CreateGraphics();
surfaceH.TranslateTransform(250, 250);
surfaceH.RotateTransform(30 * DateTime.Now.Hour);
surfaceSec = panel1.CreateGraphics();
surfaceSec.TranslateTransform(250, 250);
surfaceSec.RotateTransform(6 * DateTime.Now.Second);
surfaceMin.DrawLine(penMin, 0, 0, 0, -200);
surfaceH.DrawLine(penH, 0, 0, 0, -120);
surfaceSec.DrawLine(penSec, 0, 0, 1, -180);
}
private void timer1_Tick(object sender, EventArgs e)
{
panel1.Refresh();
}
}
}
根据我的作业,这是正确的,但我不禁认为一定有更好的方法来做。
我对 C# 还不是很了解,所以如果你能给我代码示例作为答案,我就更有可能理解它...
闪烁来自计时器的滴答声,它非常快,您可以在 timer1_tick 方法中创建一个检查,确保一秒钟实际上已经过了一秒钟,然后更新绘图。
您还可以使用计时器,告诉它何时开始以及您希望它多久更新一次。这样你就可以实时关注你自己的电脑秒数
我建议创建一个启用适当双缓冲的自定义控件:
public class Canvas : Control
{
public Canvas()
{
this.SetStyle( ControlStyles.AllPaintingInWmPaint, true );
this.SetStyle( ControlStyles.OptimizedDoubleBuffer, true );
this.SetStyle( ControlStyles.UserPaint, true );
this.SetStyle( ControlStyles.ResizeRedraw, true );
}
}
将您的绘制代码挂接到 Paint
事件并使用 Invalidate
触发重绘。切勿使用 CreateGraphics
,绘制提供给事件的图形对象。这将使您的绘图完全无闪烁!
private void canvas1_Paint( object sender, PaintEventArgs e )
{
// do your painting here, using the Graphics object passed to
// you in the PaintEventArgs
Pen penMin = new Pen( Color.Pink, 2 );
Pen penH = new Pen( Color.Red, 3 );
Pen penSec = new Pen( Color.DeepPink, 1 );
Pen black = new Pen( Color.Black, 4f );
e.Graphics.TranslateTransform( 250, 250 );
e.Graphics.DrawEllipse( black, -220, -220, 440, 440 );
e.Graphics.ResetTransform();
e.Graphics.TranslateTransform( 250, 250 );
e.Graphics.RotateTransform( 6 * DateTime.Now.Minute );
e.Graphics.DrawLine( penMin, 0, 0, 0, -200 );
e.Graphics.ResetTransform();
e.Graphics.TranslateTransform( 250, 250 );
e.Graphics.RotateTransform( 30 * DateTime.Now.Hour );
e.Graphics.DrawLine( penH, 0, 0, 0, -120 );
e.Graphics.ResetTransform();
e.Graphics.TranslateTransform( 250, 250 );
e.Graphics.RotateTransform( 6 * DateTime.Now.Second );
e.Graphics.DrawLine( penSec, 0, 0, 1, -180 );
}
我创建了一个可以根据实时时间正常工作的模拟时钟。
我不希望你为我解决这个问题或其他任何事情 - 我的代码已经可以工作了,但它闪烁得很厉害,而且由于我的知识有限,我无法确定我需要更改的到底是什么停止闪烁。
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 ClockAndStuff
{
public partial class TheName : Form
{
public TheName()
{
InitializeComponent();
timer1.Start();
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
Graphics surfaceBckg;
Graphics surfaceMin;
Graphics surfaceH;
Graphics surfaceSec;
Pen penMin = new Pen(Color.Pink,2);
Pen penH = new Pen(Color.Red,3);
Pen penSec = new Pen(Color.DeepPink,1);
Pen black = new Pen(Color.Black, 4F);
surfaceBckg = panel1.CreateGraphics();
surfaceBckg.TranslateTransform(250, 250);
surfaceBckg.DrawEllipse(black,-220,-220,440,440);
surfaceMin = panel1.CreateGraphics();
surfaceMin.TranslateTransform(250, 250);
surfaceMin.RotateTransform(6 * DateTime.Now.Minute);
surfaceH = panel1.CreateGraphics();
surfaceH.TranslateTransform(250, 250);
surfaceH.RotateTransform(30 * DateTime.Now.Hour);
surfaceSec = panel1.CreateGraphics();
surfaceSec.TranslateTransform(250, 250);
surfaceSec.RotateTransform(6 * DateTime.Now.Second);
surfaceMin.DrawLine(penMin, 0, 0, 0, -200);
surfaceH.DrawLine(penH, 0, 0, 0, -120);
surfaceSec.DrawLine(penSec, 0, 0, 1, -180);
}
private void timer1_Tick(object sender, EventArgs e)
{
panel1.Refresh();
}
}
}
根据我的作业,这是正确的,但我不禁认为一定有更好的方法来做。
我对 C# 还不是很了解,所以如果你能给我代码示例作为答案,我就更有可能理解它...
闪烁来自计时器的滴答声,它非常快,您可以在 timer1_tick 方法中创建一个检查,确保一秒钟实际上已经过了一秒钟,然后更新绘图。
您还可以使用计时器,告诉它何时开始以及您希望它多久更新一次。这样你就可以实时关注你自己的电脑秒数
我建议创建一个启用适当双缓冲的自定义控件:
public class Canvas : Control
{
public Canvas()
{
this.SetStyle( ControlStyles.AllPaintingInWmPaint, true );
this.SetStyle( ControlStyles.OptimizedDoubleBuffer, true );
this.SetStyle( ControlStyles.UserPaint, true );
this.SetStyle( ControlStyles.ResizeRedraw, true );
}
}
将您的绘制代码挂接到 Paint
事件并使用 Invalidate
触发重绘。切勿使用 CreateGraphics
,绘制提供给事件的图形对象。这将使您的绘图完全无闪烁!
private void canvas1_Paint( object sender, PaintEventArgs e )
{
// do your painting here, using the Graphics object passed to
// you in the PaintEventArgs
Pen penMin = new Pen( Color.Pink, 2 );
Pen penH = new Pen( Color.Red, 3 );
Pen penSec = new Pen( Color.DeepPink, 1 );
Pen black = new Pen( Color.Black, 4f );
e.Graphics.TranslateTransform( 250, 250 );
e.Graphics.DrawEllipse( black, -220, -220, 440, 440 );
e.Graphics.ResetTransform();
e.Graphics.TranslateTransform( 250, 250 );
e.Graphics.RotateTransform( 6 * DateTime.Now.Minute );
e.Graphics.DrawLine( penMin, 0, 0, 0, -200 );
e.Graphics.ResetTransform();
e.Graphics.TranslateTransform( 250, 250 );
e.Graphics.RotateTransform( 30 * DateTime.Now.Hour );
e.Graphics.DrawLine( penH, 0, 0, 0, -120 );
e.Graphics.ResetTransform();
e.Graphics.TranslateTransform( 250, 250 );
e.Graphics.RotateTransform( 6 * DateTime.Now.Second );
e.Graphics.DrawLine( penSec, 0, 0, 1, -180 );
}