使用面板绘画事件时图形闪烁
我创建了一个模拟时钟,可以根据实时正常工作。使用面板绘画事件时图形闪烁
我不想让你为我解决它 - 我的代码已经在工作,但它闪烁很多,而且我的知识有限,我无法确定究竟是什么,我需要改变停止闪烁。
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#还大,所以如果你能给我的代码示例作为一个答案有更大的可能性,我就可以去了解它...
我建议建立一个自定义的控制,使适当的双缓冲:
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);
}
刚才你是什么意思的“从不使用CreateGraphics”?我的意思是,它显然告诉我不要使用它,但我不知道还有什么可以做的。但我认为有限的知识是我的问题在这里.. – Keashi 2015-01-04 11:36:32
查看更新的答案。 – Chris 2015-01-04 11:39:40
当我改变它时,它根本没有手臂。例如: 'e.Graphics.TranslateTransform(250,250);' 'e.Graphics.RotateTransform(6 * DateTime.Now.Second);' 'e.Graphics.DrawLine(penSec,0,0,1, -180);' 等 – Keashi 2015-01-04 11:51:31
的闪烁来自计时器滴答,速度非常快,您可以在timer1_tick方法中创建一个检查,以确保第二个实际已经过了一秒钟,然后更新绘图。
您也可以使用计时器,在计时器中告诉它何时开始以及您希望更新的频率。由你可以按照你自己的电脑秒钟实时
timer_tick被多久调用一次? – rene 2015-01-04 11:15:34
你可以找到很多解决方案,像[this](http://stackoverflow.com/questions/16882921/how-to-fix-panel-flickering-when-redrawing),[this](http://stackoverflow.com/问题/ 8046560/how-to-stop-flickering -c-sharp-winforms)或[this](http://stackoverflow.com/questions/4777135/how-can-i-draw-on-panel-so-it -does-not-blink) – Grundy 2015-01-04 11:18:52
@Grundy我已经看到了所有这些链接,但我根本无法确定如何使用它们来解决我的问题,这就是为什么我再次问** **的具体细节我的问题 – Keashi 2015-01-04 11:31:47