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 阅读(3744) 评论(14)  编辑 收藏 网摘

评论

#1楼 2007-12-16 17:46 zeus2      

我也写过个,总觉得指针不直。有没啥办法解决啊。   回复  引用  查看    

#2楼 2007-12-16 17:47 .NET的春天      

看起来蛮精致呢,我以前也做过一个,不过是数字时钟加图片;
学习一下!
  回复  引用  查看    

#3楼 2007-12-16 18:26 we[未注册用户]

楼主,启用抗锯齿的功能试试。   回复  引用    

#4楼[楼主] 2007-12-16 18:28 Jeffery Sun      

@zeus2
有2个办法可以解决不直的问题,
1,设置Graphics的属性,g.SmoothingMode = SmoothingMode.HighQuality;
2,用Png图片来做指针和表盘,效果虽然很棒,但是GDI+画PNG的速度比较慢。可以把用PNG文件创建TextureBrush,用这个brush可以提高速度。
  回复  引用  查看    

#5楼 2007-12-16 18:29 finesite      

收藏 以后学习   回复  引用  查看    

#6楼 2007-12-16 19:46 无常      

@we

怎么启用?
  回复  引用  查看    

#7楼[楼主] 2007-12-16 20:04 Jeffery Sun      

@无常
设置Graphics的属性,g.SmoothingMode = SmoothingMode.HighQuality
  回复  引用  查看    

#8楼 2007-12-17 02:41 米开朗基罗      

@Jeffery Sun
发一张smooth的图吧。
看到了这个:
RotateTransform
GDI+功能真多。

  回复  引用  查看    

#9楼 2007-12-17 09:11 置身珠海,学习与奋斗      

有闪烁,用双缓冲试试   回复  引用  查看    

#10楼 2007-12-17 12:51 boy5d[未注册用户]

http://www.boy5d.com/article/html/2007-12/759.html
收藏了
  回复  引用    

#11楼[楼主] 2007-12-17 21:47 Jeffery Sun      

@米开朗基罗
传好了。
  回复  引用  查看    

#12楼 2007-12-24 15:31 Kobi[未注册用户]

恩,研究,研究   回复  引用    

#13楼 2007-12-28 09:43 wwd[未注册用户]

请楼主讲一下位置的计算方法。谢谢!   回复  引用    

#14楼 2009-06-28 08:08 Sun——[未注册用户]

请问版主,你的时钟怎么显示时间不对,是镜面效果   回复  引用    




发表评论

昵称: [登录] [注册]

主页:

邮箱:(仅博主可见)

评论内容:

  登录  注册

[使用Ctrl+Enter键快速提交评论]

0 996749




相关文章:

相关链接: