• GDI+自定义时钟控件


    说明:模拟带表盘的时钟
      1 using System;
      2 using System.Windows.Forms;
      3 using System.Drawing;
      4 using System.Drawing.Drawing2D;
      5 using System.Globalization;
      6 
      7 
      8 namespace BugQiang.Clocks {
      9     public class Clock : UserControl {
     10 
     11         Timer _timer;
     12 
     13         Graphics _grahpics;
     14 
     15         /// <summary>
     16         /// 坐标原点X
     17         /// </summary>
     18         float _centerX;
     19 
     20         /// <summary>
     21         /// 坐标原点Y
     22         /// </summary>
     23         float _centerY;
     24 
     25         /// <summary>
     26         /// 外圆的外接矩阵
     27         /// </summary>
     28         Rectangle _outerEllipse;
     29 
     30         /// <summary>
     31         /// 内圆的外接矩阵
     32         /// </summary>
     33         Rectangle _innerEllipse;
     34 
     35         /// <summary>
     36         /// 内圆半径
     37         /// </summary>
     38         float _innerEllipseRadius;
     39 
     40         //时分秒针的长度
     41         float _hourLength;
     42         float _minuteLength;
     43         float _secondLength;
     44 
     45         //外圆以及内圆与控件边界的距离
     46         int _outerSpan = 2;
     47         int _innerSpan = 5;
     48 
     49         /// <summary>
     50         /// 刻度长度
     51         /// </summary>
     52         float _scaleLength;
     53 
     54         Pen _outerEllipsePen;
     55         SolidBrush _innerEllipseBrush;
     56 
     57         Pen _bigScalePen;
     58         Pen _littleScalePen;
     59 
     60         SolidBrush _scaleValueBrush;
     61 
     62         Pen _hourPen;
     63         Pen _minutePen;
     64         Pen _secondPen;
     65 
     66         /// <summary>
     67         /// Hour的角度
     68         /// </summary>
     69         /// <remarks>平面直角坐标系正Y轴方向为参考</remarks>
     70         public float HourAngle {
     71             get {
     72                 return (DateTime.Now.Hour
     73                         + DateTime.Now.Minute / 60.0F
     74                         + DateTime.Now.Second / 3600.0F
     75                         + DateTime.Now.Millisecond / 3600000.0F) * 30F;
     76             }
     77         }
     78 
     79         /// <summary>
     80         /// Minute的角度
     81         /// </summary>
     82         /// <remarks>平面直角坐标系正Y轴方向为参考</remarks>
     83         public float MinuteAngle {
     84             get {
     85                 return (DateTime.Now.Minute
     86                         + DateTime.Now.Second / 60.0F
     87                         + DateTime.Now.Millisecond / 60000.0F) * 6F;
     88             }
     89         }
     90 
     91         /// <summary>
     92         /// Second的角度
     93         /// </summary>
     94         /// <remarks>平面直角坐标系正Y轴方向为参考</remarks>
     95         public float SecondAngle {
     96             get { return (DateTime.Now.Second + DateTime.Now.Millisecond / 1000.0F) * 6F; }
     97         }
     98 
     99         public Clock() {
    100             InitializeComponent();
    101             Initialize();
    102             Initialize2();
    103         }
    104 
    105         protected virtual void Initialize() {
    106             this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    107             this.SetStyle(ControlStyles.DoubleBuffer, true);
    108             this.SetStyle(ControlStyles.ResizeRedraw, true);
    109             this.SetStyle(ControlStyles.Selectable, true);
    110             this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
    111             this.SetStyle(ControlStyles.UserPaint, true);
    112             _timer = new Timer();
    113             _timer.Enabled = true; //激活计时器
    114             _timer.Interval = 50; //秒针每0.05秒刷新一次
    115             _timer.Tick += delegate { this.Invalidate(); };
    116             this.Resize += delegate {
    117                 Width = Height;
    118                 Initialize2();
    119             };
    120 
    121             _outerEllipsePen = new Pen(Color.Black, 3);
    122             _innerEllipseBrush = new SolidBrush(Color.Gray);
    123 
    124             _bigScalePen = new Pen(Color.Black, 4);
    125             _littleScalePen = new Pen(Color.Black, 1);
    126 
    127             _scaleValueBrush = new SolidBrush(Color.White);
    128 
    129             _hourPen = new Pen(Color.White, 2.5F);
    130 
    131             _minutePen = new Pen(Color.Wheat, 1.75F);
    132 
    133             _secondPen = new Pen(Color.WhiteSmoke, 0.75F);
    134         }
    135 
    136         private void Initialize2() {
    137             _centerX = Width / 2;
    138             _centerY = Height / 2;
    139 
    140             _outerEllipse = new Rectangle(_outerSpan, _outerSpan, Width - _outerSpan * 2, Height - _outerSpan * 2);
    141             _innerEllipse = new Rectangle(_innerSpan, _innerSpan, Width - _innerSpan * 2, Height - _innerSpan * 2);
    142 
    143             _innerEllipseRadius = Width / 2 - _innerSpan;
    144 
    145             _hourLength = _innerEllipseRadius * 0.50F;
    146             _minuteLength = _innerEllipseRadius * 0.75F;
    147             _secondLength = _innerEllipseRadius * 0.90F;
    148 
    149             _scaleLength = 10;
    150 
    151         }
    152 
    153         protected override void OnPaint(PaintEventArgs e) {
    154             base.OnPaint(e);
    155             _grahpics = e.Graphics;
    156             _grahpics.SmoothingMode = SmoothingMode.HighQuality;
    157 
    158             ////绘外圆以及内圆
    159             _grahpics.DrawEllipse(_outerEllipsePen, _outerEllipse);
    160             _grahpics.FillEllipse(_innerEllipseBrush, _innerEllipse);
    161 
    162             ////绘小刻度
    163             ResetTransformCenter();165                 _grahpics.FillEllipse(new SolidBrush(Color.White), -5, -5, 10, 10); //绘中心圆点164             
              for (int i = 0; i < 60; i++) {
    166 _grahpics.DrawLine(_littleScalePen, _innerEllipseRadius - _scaleLength, 0, _innerEllipseRadius, 0); 167 _grahpics.RotateTransform(6); 168 } 169 170 ////绘大刻度 171 ResetTransformCenter(); 172 for (int i = 0; i < 12; i++) { 173 _grahpics.DrawLine(_bigScalePen, _innerEllipseRadius - _scaleLength, 0, _innerEllipseRadius, 0); 174 _grahpics.RotateTransform(30); 175 } 176 177 ////绘刻度值 178 float x = 0F; 179 float y = 0F; 180 ResetTransformCenter(_centerX - 10, y + _innerEllipseRadius / 5F); 181 _grahpics.DrawString("12", 182 new Font("Times New Roman", 14, GraphicsUnit.Pixel), 183 _scaleValueBrush, 184 new PointF(x, 0)); 185 for (int i = 1; i < 6; i++) { 186 x = (float)(_innerEllipseRadius * Math.Sin(Math.PI * i / 6)); 187 y = (float)(_innerEllipseRadius * (1 - Math.Cos(Math.PI * i / 6))); 188 ResetTransformCenter(_centerX, y); 189 if (i == 3) { 190 _grahpics.DrawString(i.ToString(CultureInfo.InvariantCulture), 191 new Font("Times New Roman", 14, GraphicsUnit.Pixel), 192 _scaleValueBrush, 193 new PointF(x - 25, 0)); 194 _grahpics.DrawString((12 - i).ToString(CultureInfo.InvariantCulture), 195 new Font("Times New Roman", 14, GraphicsUnit.Pixel), 196 _scaleValueBrush, 197 new PointF(-x + 15, 0)); 198 } else if (i < 3) { 199 _grahpics.DrawString(i.ToString(CultureInfo.InvariantCulture), 200 new Font("Times New Roman", 14, GraphicsUnit.Pixel), 201 _scaleValueBrush, 202 new PointF(x - 25, _innerEllipseRadius / 6F)); 203 _grahpics.DrawString((12 - i).ToString(CultureInfo.InvariantCulture), 204 new Font("Times New Roman", 14, GraphicsUnit.Pixel), 205 _scaleValueBrush, 206 new PointF(-x + _innerEllipseRadius / 8F, _innerEllipseRadius / 6F)); 207 } else if (i > 3) { 208 _grahpics.DrawString(i.ToString(CultureInfo.InvariantCulture), 209 new Font("Times New Roman", 14, GraphicsUnit.Pixel), 210 _scaleValueBrush, 211 new PointF(x - 25, -_innerEllipseRadius / 6F)); 212 _grahpics.DrawString((12 - i).ToString(CultureInfo.InvariantCulture), 213 new Font("Times New Roman", 14, GraphicsUnit.Pixel), 214 _scaleValueBrush, 215 new PointF(-x + _innerEllipseRadius / 8F, -_innerEllipseRadius / 6F)); 216 } 217 } 218 x = 0F; 219 y = _innerEllipseRadius * 2; 220 ResetTransformCenter(_centerX - 5, y - _innerEllipseRadius / 5F); 221 _grahpics.DrawString("6", 222 new Font("Times New Roman", 14, GraphicsUnit.Pixel), 223 _scaleValueBrush, 224 new PointF(x, 0)); 225 226 ////绘秒针 227 ResetTransformCenter(); 228 _grahpics.RotateTransform(-90); 229 _grahpics.RotateTransform(SecondAngle); 230 _grahpics.DrawLine(_secondPen, -20, 0, _secondLength, 0); 231 232 ////绘分针 233 ResetTransformCenter(); 234 _grahpics.RotateTransform(-90); 235 _grahpics.RotateTransform(MinuteAngle); 236 _grahpics.DrawLine(_minutePen, 0, 0, _minuteLength, 0); 237 238 ////绘时针 239 ResetTransformCenter(); 240 _grahpics.RotateTransform(-90); 241 _grahpics.RotateTransform(HourAngle); 242 _grahpics.DrawLine(_hourPen, 0, 0, _hourLength, 0); 243 } 244 245 /// <summary> 246 /// 重置坐标原点(_centerX,_centerY) 247 /// </summary> 248 private void ResetTransformCenter() { 249 ResetTransformCenter(_centerX, _centerY); 250 } 251 252 /// <summary> 253 /// 重置坐标原点(centerX,centerY) 254 /// </summary> 255 /// <param name="centerX">坐标原点X</param> 256 /// <param name="centerY">坐标原点Y</param> 257 /// <remarks>坐标(centerX,centerY)以控件的右上角为参考点</remarks> 258 private void ResetTransformCenter(float centerX, float centerY) { 259 _grahpics.ResetTransform(); 260 _grahpics.TranslateTransform(centerX, centerY); 261 } 262 263 264 /// <summary> 265 /// 必需的设计器变量。 266 /// </summary> 267 private System.ComponentModel.IContainer components = null; 268 269 /// <summary> 270 /// 清理所有正在使用的资源。 271 /// </summary> 272 /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param> 273 protected override void Dispose(bool disposing) { 274 if (disposing && (components != null)) { 275 components.Dispose(); 276 } 277 278 if (disposing && _outerEllipsePen != null) 279 _outerEllipsePen.Dispose(); 280 if (disposing && _innerEllipseBrush != null) 281 _innerEllipseBrush.Dispose(); 282 283 if (disposing && _bigScalePen != null) 284 _bigScalePen.Dispose(); 285 if (disposing && _littleScalePen != null) 286 _littleScalePen.Dispose(); 287 288 if (disposing && _scaleValueBrush != null) 289 _scaleValueBrush.Dispose(); 290 291 if (disposing && _hourPen != null) 292 _hourPen.Dispose(); 293 if (disposing && _minutePen != null) 294 _minutePen.Dispose(); 295 if (disposing && _secondPen != null) 296 _secondPen.Dispose(); 297 298 base.Dispose(disposing); 299 } 300 301 #region 组件设计器生成的代码 302 303 /// <summary> 304 /// 设计器支持所需的方法 - 不要 305 /// 使用代码编辑器修改此方法的内容。 306 /// </summary> 307 private void InitializeComponent() { 308 this.SuspendLayout(); 309 // 310 // Clock 311 // 312 this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); 313 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; 314 this.Name = "Clock"; 315 this.Size = new System.Drawing.Size(227, 223); 316 this.ResumeLayout(false); 317 } 318 319 #endregion 320 } 321 }

    PS:.NET坐标系,以画布的左上角为原点,分别取平面直角坐标系的正X以及负Y(.NET作为正Y).

  • 相关阅读:
    【Rust】字符串切片(二)
    图像重叠操作
    LBPH
    级联分类器 CascadeClassifier
    关于linux下安装yum(安装失败遇到的坑)
    File "stdin" , line 1
    ubuntu删除了python恢复_Ubuntu16.04 不小心删除 /usr/bin/python解决办法
    Mat 类
    VideoCapture 类
    EigenFace
  • 原文地址:https://www.cnblogs.com/BugQiang/p/3175685.html
Copyright © 2020-2023  润新知