模拟时钟 - 在绘制新图像之前无法删除先前的图像

时间:2017-02-13 17:04:40

标签: c# winforms

我想为我正在编写的程序组装一个模拟时钟。我有关于数学正确等的时钟工作,但是在生成钟面的新图像之前,我无法从上一个滴答中删除图像。我的代码在下面,我认为cg.Dispose();行会这样做,但它不想这样做。我也尝试在每次滴答结束时处理Bitmap,但它也会在那里引发错误。在表单中,我有一个pictureBox和一个长度为1000ms的计时器。另外值得注意的是我有表盘的代码,但我还没有把它包括在内!

    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 ClockStreamlined
    {
public partial class Form1 : Form
{
    Bitmap bmp;
    Graphics cg;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {

        timer1.Enabled = true;
        bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);

    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        pictureBox1.Refresh();
        cg = Graphics.FromImage(bmp);
        // Get components of the DateTime
        DateTime DateTimenow = DateTime.Now;
        double hour = DateTimenow.Hour;
        double minute = DateTimenow.Minute;
        double second = DateTimenow.Second;

        // Define increment movements for each clock hand
        double hourHandangle = (30 * hour) + (minute * 0.5);
        double minuteHandangle = 6 * minute;
        double secondHandangle = 6 * second;

        // Define xy position variables for hour minute & second
        double x_hour = 0;

        double x_minute = 0;

        double x_second = 0;

        // Calculate hour hand position

        double y_hour = -(((pictureBox1.Width) / 2) - 50) * Math.Cos((hourHandangle * 2 * Math.PI) / 360);
        if (hourHandangle >= 0 && hourHandangle <= 180)
        {
            x_hour = (((pictureBox1.Width) / 2) - 50) * Math.Sin((hourHandangle * 2 * Math.PI) / 360);
        }

        else
        {   
            x_hour = -(((pictureBox1.Width) / 2) - 50) * -1 * Math.Sin((hourHandangle * 2 * Math.PI) / 360);
        }

        // Calculate minute hand position

        double y_minute = -(((pictureBox1.Width) / 2) - 30) * Math.Cos((minuteHandangle * 2 * Math.PI) / 360);

        if (minuteHandangle >= 0 && minuteHandangle <= 100)
        {
            x_minute = (((pictureBox1.Width) / 2) - 30) * Math.Sin((minuteHandangle * 2 * Math.PI) / 360);
        }
        else
        {
            x_minute = -(((pictureBox1.Width) / 2) - 30) * -1 * Math.Sin((minuteHandangle * 2 * Math.PI) / 360);
        }

        // Calculate second hand position
        double y_second = -(((pictureBox1.Width) / 2) - 10) * Math.Cos((secondHandangle * 2 * Math.PI) / 360);
        if (secondHandangle >= 0 && secondHandangle <= 100)
        {
            x_second = (((pictureBox1.Width) / 2) - 10) * Math.Sin((secondHandangle * 2 * Math.PI) / 360);
        }
        else
        {
            x_second = -(((pictureBox1.Width) / 2) - 10) * -1 * Math.Sin((secondHandangle * 2 * Math.PI) / 360);
        }

        // Get points that define hour hand
        int y_hrpoint = Convert.ToInt32(y_hour);
        int x_hrpoint = Convert.ToInt32(x_hour);

        // Get points that define minute hand
        int y_minpoint = Convert.ToInt32(y_minute);
        int x_minpoint = Convert.ToInt32(x_minute);

        // Get points that define second hand
        int x_secpoint = Convert.ToInt32(x_second);
        int y_secpoint = Convert.ToInt32(y_second);

        // Create pen
        Pen blackPen = new Pen(Color.Black, 3);

        // Create points that define hour hand
        Point point1hr = new Point(x_hrpoint + ((pictureBox1.Width) / 2), y_hrpoint + ((pictureBox1.Width) / 2));
        Point point2hr = new Point(((pictureBox1.Width) / 2), ((pictureBox1.Width) / 2));

        // Create points that define minute hand
        Point point1min = new Point(x_minpoint + ((pictureBox1.Width) / 2), y_minpoint + ((pictureBox1.Width) / 2));
        Point point2min = new Point(((pictureBox1.Width) / 2), ((pictureBox1.Width) / 2));

        // Create points that define second hand
        Point point1sec = new Point(x_secpoint + ((pictureBox1.Width) / 2), y_secpoint + ((pictureBox1.Width) / 2));
        Point point2sec = new Point(((pictureBox1.Width) / 2), ((pictureBox1.Width) / 2));

        // Draw to Bitmap
        // Draw line to screen.
        cg.DrawLine(blackPen, point1hr, point2hr);
        cg.DrawLine(blackPen, point1min, point2min);
        cg.DrawLine(blackPen, point1sec, point2sec);
        pictureBox1.Image = bmp;
        cg.Dispose();
        Invalidate();

    }
}
    }

2 个答案:

答案 0 :(得分:1)

bmp函数中设置timer1_Tick个局部变量,并在每次bmp开头创建timer1_Tick位图。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        timer1.Enabled = true;

    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        Bitmap bmp = new Bitmap(pictureBox1.Width, pictureBox1.Height);;
        Graphics cg = Graphics.FromImage(bmp);

        // your other code from timer1_Tick
        // Get components of the DateTime
        DateTime DateTimenow = DateTime.Now;
        double hour = DateTimenow.Hour;
        double minute = DateTimenow.Minute;
        double second = DateTimenow.Second;

        // ....

        pictureBox1.Image = bmp;
        cg.Dispose();
    }
}

答案 1 :(得分:1)

清除上一张图纸您需要使用您想要的任何背景颜色调用cg.Clear(Color.White)

您的计时器勾选使面板无效,然后面板的OnPaint事件进行实际绘图也会更好。您实际上也不需要使用位图。

public Form1()
{
    InitializeComponent();
}

private void timer1_Tick(object sender, EventArgs e)
{
    pictureBox1.Invalidate();
}

private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
    // Compute hand positions.
    // ...


    // Clear the previous drawing.
    e.Graphics.Clear(Color.White);

    // Create pen, draw the hands.
    using (Pen blackPen = new Pen(Color.Black, 3))
    {
        e.Graphics.DrawLine(blackPen, point1hr, point2hr);
        e.Graphics.DrawLine(blackPen, point1min, point2min);
        e.Graphics.DrawLine(blackPen, point1sec, point2sec);
    }
}