使用Panel paint事件时图形闪烁

时间:2015-01-04 11:11:24

标签: c# winforms graphics

我创建了一个模拟时钟,可以根据实时情况正常工作。

我不希望你为我或任何事情解决它 - 我的代码已经在运作,但它的重复闪烁,而且由于我的知识有限,我无法确定究竟是什么我需要改变以停止闪烁。

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

2 个答案:

答案 0 :(得分:1)

我建议创建一个自定义控件来启用正确的双缓冲:

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

答案 1 :(得分:0)

闪烁来自计时器滴答,这非常快,您可以在timer1_tick方法中创建一个检查,确保第二个实际上已经过了一秒,然后更新绘图。

您还可以使用计时器,在该计时器中,您可以告诉它何时开始以及您希望它更新的频率。通过这种方式,您可以实时跟踪自己的计算机