使用面板绘画事件时图形闪烁

问题描述:

我创建了一个模拟时钟,可以根据实时正常工作。使用面板绘画事件时图形闪烁

我不想让你为我解决它 - 我的代码已经在工作,但它闪烁很多,而且我的知识有限,我无法确定究竟是什么,我需要改变停止闪烁。

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#还大,所以如果你能给我的代码示例作为一个答案有更大的可能性,我就可以去了解它...

This is what it looks like

+0

timer_tick被多久调用一次? – rene 2015-01-04 11:15:34

+2

你可以找到很多解决方案,像[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

+0

@Grundy我已经看到了所有这些链接,但我根本无法确定如何使用它们来解决我的问题,这就是为什么我再次问** **的具体细节我的问题 – Keashi 2015-01-04 11:31:47

我建议建立一个自定义的控制,使适当的双缓冲:

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); 
} 
+0

刚才你是什么意思的“从不使用CreateGraphics”?我的意思是,它显然告诉我不要使用它,但我不知道还有什么可以做的。但我认为有限的知识是我的问题在这里.. – Keashi 2015-01-04 11:36:32

+0

查看更新的答案。 – Chris 2015-01-04 11:39:40

+0

当我改变它时,它根本没有手臂。例如: '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方法中创建一个检查,以确保第二个实际已经过了一秒钟,然后更新绘图。

您也可以使用计时器,在计时器中告诉它何时开始以及您希望更新的频率。由你可以按照你自己的电脑秒钟实时

+0

呜!所以我试了一下,几乎完全停止了 - 只有每隔一段时间它会闪烁几次,然后恢复正常。永远不会认为它是这样简单的:) – Keashi 2015-01-04 11:22:51

+0

因为它的一个学校项目我不会告诉你如何做到这一点,但我可以给你一个地方看看,但是你已经在计时器上有一个间隔属性使用:) – 2015-01-04 11:27:21

+0

闪烁只有*少*与更大的计时器间隔。请查看解决方案,了解如何使其停止*。这只是一个绷带,而不是一种治疗方法。 – nvoigt 2015-01-04 11:32:37