C#个性化时钟控件之2(含源码)
先看效果:

1、首先,定义显示时钟的样式:SevenSegmentClockStyle
//SevenSegmentClockStyle.cs
using System; namespace BrawDraw.Com.PhotoFrame.Net.PublicFunctions { /// <summary> /// Clock's Style. /// </summary> public enum SevenSegmentClockStyle { DateOnly, TimeOnly, DateAndTime } }
如果使用SevenSegmentClockStyle.DateOnly则效果如下:
如果使用SevenSegmentClockStyle.TimeOnly,其效果如下:
2、定义用于显示时间的8字型段码:
//SevenSegmentDisplay.cs using System; using System.Drawing; using System.Windows.Forms; namespace BrawDraw.Com.PhotoFrame.Net.PublicFunctions { class SevenSegmentDisplay { Graphics grfx; Brush _brush = Brushes.Black; bool _isDrawShadow = true; Color _shadowColor = Color.FromArgb(60, Color.White); Brush _shadowBrush = null; // Indicates what segments are illuminated for all 10 digits static byte[,] bySegment = { {1, 1, 1, 0, 1, 1, 1}, // 0 {0, 0, 1, 0, 0, 1, 0}, // 1 {1, 0, 1, 1, 1, 0, 1}, // 2 {1, 0, 1, 1, 0, 1, 1}, // 3 {0, 1, 1, 1, 0, 1, 0}, // 4 {1, 1, 0, 1, 0, 1, 1}, // 5 {1, 1, 0, 1, 1, 1, 1}, // 6 {1, 0, 1, 0, 0, 1, 0}, // 7 {1, 1, 1, 1, 1, 1, 1}, // 8 {1, 1, 1, 1, 0, 1, 1} // 9 }; // Points that define each of the seven segments readonly Point[][] apt = new Point[7][]; public bool IsDrawShadow { get { return this._isDrawShadow; } set { this._isDrawShadow = value; } } public SevenSegmentDisplay(Graphics grfx) { this.grfx = grfx; // Initialize jagged Point array. apt[0] = new Point[] { new Point( 3, 2), new Point(39, 2), new Point(31, 10), new Point(11, 10) }; apt[1] = new Point[] { new Point( 2, 3), new Point(10, 11), new Point(10, 31), new Point( 2, 35) }; apt[2] = new Point[] { new Point(40, 3), new Point(40, 35), new Point(32, 31), new Point(32, 11) }; apt[3] = new Point[] { new Point( 3, 36), new Point(11, 32), new Point(31, 32), new Point(39, 36), new Point(31, 40), new Point(11, 40) }; apt[4] = new Point[] { new Point( 2, 37), new Point(10, 41), new Point(10, 61), new Point( 2, 69) }; apt[5] = new Point[] { new Point(40, 37), new Point(40, 69), new Point(32, 61), new Point(32, 41) }; apt[6] = new Point[] { new Point(11, 62), new Point(31, 62), new Point(39, 70), new Point( 3, 70) }; } public SizeF MeasureString(string str, Font font) { SizeF sizef = new SizeF(0, grfx.DpiX * font.SizeInPoints / 72); for (int i = 0; i < str.Length; i++) { if (Char.IsDigit(str[i])) { sizef.Width += 42 * grfx.DpiX * font.SizeInPoints / 72 / 72; } else if (str[i] == '-') { sizef.Width += 42 * grfx.DpiX * font.SizeInPoints / 72 / 72; } else if (str[i] == ':') { sizef.Width += 12 * grfx.DpiX * font.SizeInPoints / 72 / 72; } else if (str[i] == ' ') { sizef.Width += 36 * grfx.DpiX * font.SizeInPoints / 72 / 72; } } return sizef; } public void DrawString(string str, Font font, Brush brush, float x, float y) { this._brush = brush; this._shadowBrush = new SolidBrush(Color.FromArgb(40, ((SolidBrush)this._brush).Color)); for (int i = 0; i < str.Length; i++) { if (Char.IsDigit(str[i])) { x = Number(str[i] - '0', font, brush, x, y); } else if (str[i] == '-') { x = MinusSign(font, brush, x, y); } else if (str[i] == ':') { x = Colon(font, brush, x, y); } else if (str[i] == ' ') { x = DrawSpace(font, brush, x, y); } } } private float Number(int num, Font font, Brush brush, float x, float y) { for (int i = 0; i < apt.Length; i++) { if(_isDrawShadow) { Fill(apt[i], font, _shadowBrush, x, y); } if (bySegment[num, i] == 1) { Fill(apt[i], font, brush, x, y); } } return x + 42 * grfx.DpiX * font.SizeInPoints / 72 / 72; } private float MinusSign(Font font, Brush brush, float x, float y) { Fill(apt[3], font, brush, x, y); return x + 42 * grfx.DpiX * font.SizeInPoints / 72 / 72; } private float DrawSpace(Font font, Brush brush, float x, float y) { return x + 36 * grfx.DpiX * font.SizeInPoints / 72 / 72; } private float Colon(Font font, Brush brush, float x, float y) { Point[][] apt = new Point[2][]; apt[0] = new Point[] { new Point( 2, 21), new Point( 6, 17), new Point(10, 21), new Point( 6, 25) }; apt[1] = new Point[] { new Point( 2, 51), new Point( 6, 47), new Point(10, 51), new Point( 6, 55) }; for (int i = 0; i < apt.Length; i++) { Fill(apt[i], font, brush, x, y); } return x + 12 * grfx.DpiX * font.SizeInPoints / 72 / 72; } private void Fill(Point[] apt, Font font, Brush brush, float x, float y) { PointF[] aptf = new PointF[apt.Length]; for (int i = 0; i < apt.Length; i++) { aptf[i].X = x + apt[i].X * grfx.DpiX * font.SizeInPoints / 72 / 72; aptf[i].Y = y + apt[i].Y * grfx.DpiY * font.SizeInPoints / 72 / 72; } grfx.FillPolygon(brush, aptf); } } } 3、定义时钟控件,从SevenSegmentClock : UserControl继承: //SevenSegmentClock.cs using System; using System.Drawing; using System.Globalization; using System.Windows.Forms; using BrawDraw.Com.PhotoFrame.Net.PublicFunctions; namespace BrawDraw.Com.PhotoFrame.Net.PublicFunctions { public class SevenSegmentClock : UserControl { DateTime _dateTime; SevenSegmentClockStyle _clockStyle = SevenSegmentClockStyle.DateAndTime; Color _clockColor = Color.Black; public System.DateTime DateTime { get { return this._dateTime; } set { this._dateTime = value; } } public System.Drawing.Color ClockColor { get { return this._clockColor; } set { this._clockColor = value; this.Invalidate(); } } public SevenSegmentClockStyle SevenSegmentClockStyle { get { return this._clockStyle; } set { this._clockStyle = value; this.Invalidate(); } } public SevenSegmentClock() { Text = "Seven-Segment Clock"; // BackColor = Color.White; ResizeRedraw = true; //MinimumSize = SystemInformation.MinimumWindowSize + new Size(0, 1); _dateTime = DateTime.Now; Timer timer = new Timer(); timer.Tick += new EventHandler(TimerOnTick); timer.Interval = 100; timer.Enabled = true; } void TimerOnTick(object obj, EventArgs ea) { DateTime dtNow = DateTime.Now; dtNow = new DateTime(dtNow.Year, dtNow.Month, dtNow.Day, dtNow.Hour, dtNow.Minute, dtNow.Second); if (dtNow != _dateTime) { _dateTime = dtNow; Invalidate(); } } protected override void OnPaint(PaintEventArgs pea) { DrawClock(pea.Graphics); } public void DrawClock(Graphics grfx) { this.DrawClock(grfx, this.ClientRectangle); } private void InitializeComponent() { // // SevenSegmentClock // this.Name = "SevenSegmentClock"; this.Size = new System.Drawing.Size(448, 64); } public void DrawClock(Graphics grfx, Rectangle destRect) { SevenSegmentDisplay ssd = new SevenSegmentDisplay(grfx); string strTime = string.Empty; if(this._clockStyle == SevenSegmentClockStyle.TimeOnly) { strTime = _dateTime.ToString("T", DateTimeFormatInfo.InvariantInfo); } else if(this._clockStyle == SevenSegmentClockStyle.DateOnly) { strTime = _dateTime.ToString("yyyy-MM-dd", DateTimeFormatInfo.InvariantInfo); } else { strTime = _dateTime.ToString("yyyy-MM-dd", DateTimeFormatInfo.InvariantInfo) + " " + _dateTime.ToString("T", DateTimeFormatInfo.InvariantInfo); } SizeF sizef = ssd.MeasureString(strTime, Font); float fScale = Math.Min(destRect.Width / sizef.Width, destRect.Height / sizef.Height); Font font = new Font(Font.FontFamily, fScale * Font.SizeInPoints); sizef = ssd.MeasureString(strTime, font); ssd.DrawString(strTime, font, new SolidBrush(this._clockColor), (destRect.Width - sizef.Width) / 2, (destRect.Height - sizef.Height) / 2); } } } 5、测试: //MainFormTest.cs using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using BrawDraw.Com.PhotoFrame.Net.PublicFunctions; namespace BrawDraw.Com.PhotoFrame.Net.PublicFunctions { /// <summary> /// MainForm 的摘要说明。 /// </summary> public class MainForm : System.Windows.Forms.Form { /// <summary> /// 必需的设计器变量。 /// </summary> private System.ComponentModel.Container components = null; private BrawDraw.Com.PhotoFrame.Net.PublicFunctions.SevenSegmentClock sevenSegmentClock1; DateTime dt; public MainForm() { // // Windows 窗体设计器支持所必需的 // InitializeComponent(); sevenSegmentClock1.SevenSegmentClockStyle = SevenSegmentClockStyle.TimeOnly; MinimumSize = SystemInformation.MinimumWindowSize + new Size(0, 1); dt = DateTime.Now; Timer timer = new Timer(); timer.Tick += new EventHandler(TimerOnTick); timer.Interval = 100; timer.Enabled = true; // // TODO: 在 InitializeComponent 调用后添加任何构造函数代码 // } /// <summary> /// 清理所有正在使用的资源。 /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if(components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows 窗体设计器生成的代码 /// <summary> /// 设计器支持所需的方法 - 不要使用代码编辑器修改 /// 此方法的内容。 /// </summary> private void InitializeComponent() { this.sevenSegmentClock1 = new BrawDraw.Com.PhotoFrame.Net.PublicFunctions.SevenSegmentClock(); this.SuspendLayout(); // // sevenSegmentClock1 // this.sevenSegmentClock1.BackColor = System.Drawing.Color.Black; this.sevenSegmentClock1.ClockColor = System.Drawing.Color.GreenYellow; this.sevenSegmentClock1.DateTime = new System.DateTime(2006, 2, 12, 18, 20, 43, 0); this.sevenSegmentClock1.Location = new System.Drawing.Point(8, 8); this.sevenSegmentClock1.Name = "sevenSegmentClock1"; this.sevenSegmentClock1.SevenSegmentClockStyle = BrawDraw.Com.PhotoFrame.Net.PublicFunctions.SevenSegmentClockStyle.DateAndTime; this.sevenSegmentClock1.Size = new System.Drawing.Size(616, 56); this.sevenSegmentClock1.TabIndex = 0; // // MainForm // this.AutoScaleBaseSize = new System.Drawing.Size(6, 14); this.ClientSize = new System.Drawing.Size(624, 253); this.Controls.Add(this.sevenSegmentClock1); this.Name = "MainForm"; this.Text = "MainForm"; this.ResumeLayout(false); } #endregion public static void Main() { Application.Run(new MainForm()); } void TimerOnTick(object obj, EventArgs ea) { DateTime dtNow = DateTime.Now; dtNow = new DateTime(dtNow.Year, dtNow.Month, dtNow.Day, dtNow.Hour, dtNow.Minute, dtNow.Second); if (dtNow != dt) { dt = dtNow; Invalidate(); } } protected override void OnPaint(PaintEventArgs pea) { // sevenSegmentClock1.DrawClock(pea.Graphics); } } }
浙公网安备 33010602011771号