2013-07-17 23 views
0

我需要在C#的窗體菜單頁中創建一個模擬時鐘。在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窗體上運行模擬時鐘。

+0

我不明白在Paint中繪製1和5分鐘刻度的點,它會一遍又一遍地繪製。如果只有時鐘指針畫在Paint中,而不是整個時鐘,那會更好。不是嗎? – Pankaj

回答

1

您提供的代碼片段看起來非常像Syed Mehroz Alam的公開可用樣本。通過快速inspecting his code它看起來像你沒有連接到定時器和窗體本身的事件。

添加以下到您的的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); 
} 

注意,如果代碼確實是從借用的,或者其他開發人員的啓發,它被認爲是良好的禮貌做出提及它。

+0

非常感謝你!首先我要承認,我並不是想要表明這個代碼是由我完成的,顯然我使用的是@Syed Mehroz Alam的代碼,但不知道具體是什麼,我只是在引用時才進行搜索。感謝您指導我的名字。 – Karishma

+0

再次感謝您成功運行的代碼。它的工作現在很好。非常感謝。!! – Karishma

2

您不能從與創建表單的線程不同的線程訪問窗體項目。 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(); 
    } 
} 

我沒有在這裏的工具來檢查代碼編譯,但它應該是這樣的。

希望它有幫助。