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 直接看代码吧{
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
Graphics g = e.Graphics;
// init the origin
g.TranslateTransform(this.Width / 2.0f, this.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 + 50, 10, 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 + 30, 6, 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 + 10, 2, dialRadius));
g.Restore(state);
}
{
Graphics g = e.Graphics;
// init the origin
g.TranslateTransform(this.Width / 2.0f, this.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 + 50, 10, 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 + 30, 6, 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 + 10, 2, 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);
}
{
InitializeComponent();
this.SetStyle(ControlStyles.ResizeRedraw, true);
}
就这么多了,代码传上来,大家自己看吧。
贴一张HighQuality的
posted on 2007-12-16 17:37 Jeffery Sun 阅读(12884) 评论(16) 编辑 收藏 举报