在C#Windows窗体中使用模拟时钟

本文关键字:模拟 时钟 C#Windows 窗体 | 更新日期: 2023-09-27 18:22:39

我需要在C#中的windows窗体菜单页中制作一个模拟时钟。

我创建了一个名为"AnalogControl"的用户控件。它使用定时器,下面是它的代码:-

 public partial class AnalogClock : UserControl
{
    const float PI = 3.141592654F;
    DateTime dateTime;
    float fRadius, fCenterX, fCenterY, fCenterCircleRadius, fHourLength;
    float fMinLength, fSecLength, fHourThickness, fMinThickness, fSecThickness;
    bool bDraw5MinuteTicks = true;
    bool bDraw1MinuteTicks = true;
    float fTicksThickness = 2;
    Color hrColor = Color.Black;
    Color minColor = Color.Black;
    Color secColor = Color.Black;
    Color circleColor = Color.Black;
    Color ticksColor = Color.Black;

    public AnalogClock()
    {
        InitializeComponent();
    }
    private void AnalogClock_Load(object sender, EventArgs e)
    {
        dateTime = DateTime.Now;
        this.AnalogClock_Resize(sender, e);
    }


    private void DrawLine(float fThickness, float fLength, Color color, float fRadians,
                          System.Windows.Forms.PaintEventArgs e)
    {
        e.Graphics.DrawLine(new Pen(color, fThickness),
            fCenterX - (float)(fLength / 9 * System.Math.Sin(fRadians)),
            fCenterY + (float)(fLength / 9 * System.Math.Cos(fRadians)),
            fCenterX + (float)(fLength * System.Math.Sin(fRadians)),
            fCenterY - (float)(fLength * System.Math.Cos(fRadians)));
    }
    private void DrawPolygon(float fThickness, float fLength, Color color, float fRadians,
                             System.Windows.Forms.PaintEventArgs e)
    {
        PointF A = new PointF((float)(fCenterX + fThickness * 2 * System.Math.Sin(fRadians + PI / 2)),
            (float)(fCenterY - fThickness * 2 * System.Math.Cos(fRadians + PI / 2)));
        PointF B = new PointF((float)(fCenterX + fThickness * 2 * System.Math.Sin(fRadians - PI / 2)),
            (float)(fCenterY - fThickness * 2 * System.Math.Cos(fRadians - PI / 2)));
        PointF C = new PointF((float)(fCenterX + fLength * System.Math.Sin(fRadians)),
            (float)(fCenterY - fLength * System.Math.Cos(fRadians)));
        PointF D = new PointF((float)(fCenterX - fThickness * 4 * System.Math.Sin(fRadians)),
            (float)(fCenterY + fThickness * 4 * System.Math.Cos(fRadians)));
        PointF[] points = { A, D, B, C };
        e.Graphics.FillPolygon(new SolidBrush(color), points);
    }
    private void AnalogClock_Paint(object sender,
          System.Windows.Forms.PaintEventArgs e)
    {
        float fRadHr = (dateTime.Hour % 12 + dateTime.Minute / 60F) * 30 * PI / 180;
        float fRadMin = (dateTime.Minute) * 6 * PI / 180;
        float fRadSec = (dateTime.Second) * 6 * PI / 180;
        DrawPolygon(this.fHourThickness,
              this.fHourLength, hrColor, fRadHr, e);
        DrawPolygon(this.fMinThickness,
              this.fMinLength, minColor, fRadMin, e);
        DrawLine(this.fSecThickness,
              this.fSecLength, secColor, fRadSec, e);

        for (int i = 0; i < 60; i++)
        {
            if (this.bDraw5MinuteTicks == true && i % 5 == 0)
            // Draw 5 minute ticks
            {
                e.Graphics.DrawLine(new Pen(ticksColor, fTicksThickness),
                  fCenterX +
                  (float)(this.fRadius / 1.50F * System.Math.Sin(i * 6 * PI / 180)),
                  fCenterY -
                  (float)(this.fRadius / 1.50F * System.Math.Cos(i * 6 * PI / 180)),
                  fCenterX +
                  (float)(this.fRadius / 1.65F * System.Math.Sin(i * 6 * PI / 180)),
                  fCenterY -
                  (float)(this.fRadius / 1.65F * System.Math.Cos(i * 6 * PI / 180)));
            }
            else if (this.bDraw1MinuteTicks == true) // draw 1 minute ticks
            {
                e.Graphics.DrawLine(new Pen(ticksColor, fTicksThickness),
                  fCenterX +
                  (float)(this.fRadius / 1.50F * System.Math.Sin(i * 6 * PI / 180)),
                  fCenterY -
                  (float)(this.fRadius / 1.50F * System.Math.Cos(i * 6 * PI / 180)),
                  fCenterX +
                  (float)(this.fRadius / 1.55F * System.Math.Sin(i * 6 * PI / 180)),
                  fCenterY -
                  (float)(this.fRadius / 1.55F * System.Math.Cos(i * 6 * PI / 180)));
            }
        }
        //draw circle at center
        e.Graphics.FillEllipse(new SolidBrush(circleColor),
                   fCenterX - fCenterCircleRadius / 2,
                   fCenterY - fCenterCircleRadius / 2,
                   fCenterCircleRadius, fCenterCircleRadius);
    }

    private void AnalogClock_Resize(object sender, EventArgs e)
    {
        this.Width = this.Height;
        this.fRadius = this.Height / 2;
        this.fCenterX = this.ClientSize.Width / 2;
        this.fCenterY = this.ClientSize.Height / 2;
        this.fHourLength = (float)this.Height / 3 / 1.85F;
        this.fMinLength = (float)this.Height / 3 / 1.20F;
        this.fSecLength = (float)this.Height / 3 / 1.15F;
        this.fHourThickness = (float)this.Height / 100;
        this.fMinThickness = (float)this.Height / 150;
        this.fSecThickness = (float)this.Height / 200;
        this.fCenterCircleRadius = this.Height / 50;
        timer1.Start();
    }
    public Color HourHandColor
    {
        get { return this.hrColor; }
        set { this.hrColor = value; }
    }
    public Color MinuteHandColor
    {
        get { return this.minColor; }
        set { this.minColor = value; }
    }
    public Color SecondHandColor
    {
        get { return this.secColor; }
        set
        {
            this.secColor = value;
            this.circleColor = value;
        }
    }
    public Color TicksColor
    {
        get { return this.ticksColor; }
        set { this.ticksColor = value; }
    }
    public bool Draw1MinuteTicks
    {
        get { return this.bDraw1MinuteTicks; }
        set { this.bDraw1MinuteTicks = value; }
    }
    public bool Draw5MinuteTicks
    {
        get { return this.bDraw5MinuteTicks; }
        set { this.bDraw5MinuteTicks = value; }
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        this.dateTime = DateTime.Now;
        this.Refresh();
    }
    public void Start()
    {
        timer1.Enabled = true;
        this.Refresh();
    }
    public void Stop()
    {
        timer1.Enabled = false;
    }

}

我正在以这种方式在另一种形式的加载事件中使用此控件:-

this.analogClock1.Start();

但问题是,在我使用"模拟控制"的页面上,它只是显示了方框,但没有显示时钟,甚至时钟也没有工作。

请帮我写代码,这样我就可以在windows窗体上运行模拟时钟了。

在C#Windows窗体中使用模拟时钟

您不能从与创建窗体的线程不同的线程访问windows窗体项。timer1_Tick在不同的线程中执行,因此您应该调用UI线程。

将计时器处理程序更改为:

private void timer1_Tick(object sender, EventArgs e)
{
    if (this.InvokeRequired())
    {
        EventHandler handler = new EventHandler(this.Timer1_Tick);
        this.Invoke(handler, new object[]{sender, e});
    }
    else
    {
        this.dateTime = DateTime.Now;
        this.Refresh();
    }
}

我这里没有一个工具来检查代码是否编译,但它应该是这样的。

希望能有所帮助。

您提供的片段看起来非常像Syed Mehroz Alam的公开样本。通过快速检查他的代码,看起来您没有连接到计时器和表单本身的事件。

将以下内容添加到InitializeComponent()中即可:

private void InitializeComponent()
{
    this.components = new System.ComponentModel.Container();
    this.timer1 = new System.Windows.Forms.Timer(this.components);
    this.SuspendLayout();
    // 
    // timer1
    // 
    this.timer1.Enabled = true;
    this.timer1.Interval = 1000;
    this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
    // 
    // AnalogClock
    // 
    this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
    this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    this.Name = "AnalogClock";
    this.Resize += new System.EventHandler(this.AnalogClock_Resize);
    this.Load += new System.EventHandler(this.AnalogClock_Load);
    this.Paint += new System.Windows.Forms.PaintEventHandler(this.AnalogClock_Paint);
    this.ResumeLayout(false);
}

请注意,如果代码确实是从另一个开发人员那里借来的,或者受到了另一个开发者的启发,那么提及它被认为是一种礼貌