WPF随笔

导航

C#自绘时钟 (附源码)

                                        C#自绘时钟

                        代码下载

    前一段写了两篇如何用C++来结合WPF进行开发的文章,今天抽时间写个指针时钟程序,代码不多,给大家做个参考,主要使用GDI+来实现,大家可以根据这些代码,加几张图片就可以画出一个漂亮的时钟,也可以领会一下GDI+中的坐标转换的方法。
    先看看效果
    
    第一步:新建一个WinForm的工程,添加一个UserControl的派生类取名ClockControl.
    第二步:DoubleBuffered属性设为true, 防止闪烁,也可以自己用MemBitmap来做,不过.NET提供了方便的DoubleBuffered,这点比C++好方便太多了。
    第三步:添加一个Timer,定时时间为1000(1 Second),即每秒刷新一次,取当前的时间。Timer的Tick事件代码如下:

private void clockTimer_Tick(object sender, EventArgs e)
{
   Invalidate();
}
    第四步:Overright OnPaint 直接看代码吧
protected override void OnPaint(PaintEventArgs e)
{
    Graphics g 
= e.Graphics;

    
// init the origin
    g.TranslateTransform(this.Width / 2.0fthis.Height / 2.0f);

    
int dialRadius = Math.Min(this.Width, this.Height) / 2;

    
// Draw the clock dial
    GraphicsState state = g.Save();

    
for (int i = 0; i<60; i++)
    
{
       
int radius = 15;
       
if (i % 5 == 0)
          radius 
= 25;

       g.FillEllipse(Brushes.Blue, 
new Rectangle(-radius / 2-dialRadius, radius, radius));

       g.RotateTransform(
360 / 60);
     }


     g.Restore(state);

     
// Get current time
     DateTime now = DateTime.Now;

     
// Draw hour hand
     state = g.Save();

     g.RotateTransform((Math.Abs(now.Hour 
- 12+ now.Minute / 60f ) * 360f / 12f);
     g.FillRectangle(Brushes.Black, 
new Rectangle(-5-dialRadius + 5010, dialRadius - 40));
            
     g.Restore(state);

     
// Draw Minute hand
            state = g.Save();

     g.RotateTransform((now.Minute 
+ now.Second / 60f) * 360f / 60f);
     g.FillRectangle(Brushes.DarkGreen, 
new Rectangle(-3-dialRadius + 306, dialRadius - 15));

     g.Restore(state);

     
// Draw Second hand
     state = g.Save();

     g.RotateTransform(now.Second 
* 360f / 60f);
     g.FillRectangle(Brushes.Red, 
new Rectangle(-1-dialRadius + 102, dialRadius));

     g.Restore(state);
}

    简单说明一下,这个Control主要使用GDI+的Transform函数, 用g.TranslateTransform(this.Width / 2.0f, this.Height / 2.0f);把坐标原点移动到中心,使用RotateTransform来旋转角度实现时钟的表皮和指针的不同位置。具体位置的计算,大家一看就知道了。
    最后再加一行代码:
public ClockControl()
{
    InitializeComponent();

     
this.SetStyle(ControlStyles.ResizeRedraw, true);
}

    就这么多了,代码传上来,大家自己看吧。 
    
    贴一张HighQuality的

posted on 2007-12-16 17:37  Jeffery Sun  阅读(12884)  评论(16编辑  收藏  举报