前提
入行已經7,8年了,一直想做一套漂亮點的自定義控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
NuGet
Install-Package HZH_Controls
複制
目錄
https://www.cnblogs.com/bfyx/p/11364884.html
用處及效果

準備工作
依然GDI+,不懂可以先百度了解下
開始
添加一個類UCAlarmLamp,繼承自UserControl
添加屬性
1 /// <summary>
2 /// The lamp color
3 /// </summary>
4 private Color[] lampColor = new Color[] { Color.FromArgb(255, 77, 59) };
5
6 /// <summary>
7 /// Gets or sets the color of the lamp.
8 /// </summary>
9 /// <value>The color of the lamp.</value>
10 [Description("燈顔色,當需要閃爍時,至少需要2個及以上顔色,不需要閃爍則至少需要1個顔色"), Category("自定義")]
11 public Color[] LampColor
12 {
13 get { return lampColor; }
14 set
15 {
16 if (value == null || value.Length <= 0)
17 return;
18 lampColor = value;
19 Refresh();
20 }
21 }
22
23 /// <summary>
24 /// The lampstand
25 /// </summary>
26 private Color lampstand = Color.FromArgb(105, 105, 105);
27
28 /// <summary>
29 /// Gets or sets the lampstand.
30 /// </summary>
31 /// <value>The lampstand.</value>
32 [Description("燈座顔色"), Category("自定義")]
33 public Color Lampstand
34 {
35 get { return lampstand; }
36 set { lampstand = value; }
37 }
38
39 /// <summary>
40 /// The twinkle speed
41 /// </summary>
42 private int twinkleSpeed = 0;
43
44 /// <summary>
45 /// Gets or sets the twinkle speed.
46 /// </summary>
47 /// <value>The twinkle speed.</value>
48 [Description("閃爍間隔時間(毫秒),當為0時不閃爍"), Category("自定義")]
49 public int TwinkleSpeed
50 {
51 get { return twinkleSpeed; }
52 set
53 {
54 if (value < 0)
55 return;
56 twinkleSpeed = value;
57 if (value == 0 || lampColor.Length <= 1)
58 {
59 timer.Enabled = false;
60 }
61 else
62 {
63 intColorIndex = 0;
64 timer.Interval = value;
65 timer.Enabled = true;
66 }
67 Refresh();
68 }
69 }
70 /// <summary>
71 /// The timer
72 /// </summary>
73 Timer timer;
74 /// <summary>
75 /// The int color index
76 /// </summary>
77 int intColorIndex = 0;
78 /// <summary>
79 /// The m rect working
80 /// </summary>
81 Rectangle m_rectWorking;
複制
重繪
1 protected override void OnPaint(PaintEventArgs e)
2 {
3 base.OnPaint(e);
4 var g = e.Graphics;
5 g.SetGDIHigh();
6
7 Color c1 = lampColor[intColorIndex];
8 GraphicsPath path = new GraphicsPath();
9 path.AddLine(new Point(m_rectWorking.Left, m_rectWorking.Bottom), new Point(m_rectWorking.Left, m_rectWorking.Top + m_rectWorking.Width));
10 path.AddArc(new Rectangle(m_rectWorking.Left, m_rectWorking.Top, m_rectWorking.Width, m_rectWorking.Width), 180f, 180f);
11 path.AddLine(new Point(m_rectWorking.Right, m_rectWorking.Top + m_rectWorking.Width), new Point(m_rectWorking.Right, m_rectWorking.Bottom));
12 path.CloseAllFigures();
13 g.FillPath(new SolidBrush(c1), path);
14
15 g.FillRectangle(new SolidBrush(lampstand), new Rectangle(5, m_rectWorking.Bottom - 19, this.Width - 10, 10));
16 g.FillRectangle(new SolidBrush(lampstand), new Rectangle(0, m_rectWorking.Bottom - 10, this.Width, 10));
17 }
複制
完整代碼
1 // ***********************************************************************
2 // Assembly : HZH_Controls
3 // Created : 2019-09-10
4 //
5 // ***********************************************************************
6 // <copyright file="UCAlarmLamp.cs">
7 // Copyright by Huang Zhenghui(黃正輝) All, QQ group:568015492 QQ:623128629 Email:[email protected]
8 // </copyright>
9 //
10 // Blog: https://www.cnblogs.com/bfyx
11 // GitHub:https://github.com/kwwwvagaa/NetWinformControl
12 // gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
13 //
14 // If you use this code, please keep this note.
15 // ***********************************************************************
16 using System;
17 using System.Collections.Generic;
18 using System.Linq;
19 using System.Text;
20 using System.Windows.Forms;
21 using System.Drawing;
22 using System.Drawing.Drawing2D;
23 using System.ComponentModel;
24
25 namespace HZH_Controls.Controls
26 {
27 /// <summary>
28 /// Class UCAlarmLamp.
29 /// Implements the <see cref="System.Windows.Forms.UserControl" />
30 /// </summary>
31 /// <seealso cref="System.Windows.Forms.UserControl" />
32 public class UCAlarmLamp : UserControl
33 {
34 /// <summary>
35 /// The lamp color
36 /// </summary>
37 private Color[] lampColor = new Color[] { Color.FromArgb(255, 77, 59) };
38
39 /// <summary>
40 /// Gets or sets the color of the lamp.
41 /// </summary>
42 /// <value>The color of the lamp.</value>
43 [Description("燈顔色,當需要閃爍時,至少需要2個及以上顔色,不需要閃爍則至少需要1個顔色"), Category("自定義")]
44 public Color[] LampColor
45 {
46 get { return lampColor; }
47 set
48 {
49 if (value == null || value.Length <= 0)
50 return;
51 lampColor = value;
52 Refresh();
53 }
54 }
55
56 /// <summary>
57 /// The lampstand
58 /// </summary>
59 private Color lampstand = Color.FromArgb(105, 105, 105);
60
61 /// <summary>
62 /// Gets or sets the lampstand.
63 /// </summary>
64 /// <value>The lampstand.</value>
65 [Description("燈座顔色"), Category("自定義")]
66 public Color Lampstand
67 {
68 get { return lampstand; }
69 set { lampstand = value; }
70 }
71
72 /// <summary>
73 /// The twinkle speed
74 /// </summary>
75 private int twinkleSpeed = 0;
76
77 /// <summary>
78 /// Gets or sets the twinkle speed.
79 /// </summary>
80 /// <value>The twinkle speed.</value>
81 [Description("閃爍間隔時間(毫秒),當為0時不閃爍"), Category("自定義")]
82 public int TwinkleSpeed
83 {
84 get { return twinkleSpeed; }
85 set
86 {
87 if (value < 0)
88 return;
89 twinkleSpeed = value;
90 if (value == 0 || lampColor.Length <= 1)
91 {
92 timer.Enabled = false;
93 }
94 else
95 {
96 intColorIndex = 0;
97 timer.Interval = value;
98 timer.Enabled = true;
99 }
100 Refresh();
101 }
102 }
103 /// <summary>
104 /// The timer
105 /// </summary>
106 Timer timer;
107 /// <summary>
108 /// The int color index
109 /// </summary>
110 int intColorIndex = 0;
111 /// <summary>
112 /// The m rect working
113 /// </summary>
114 Rectangle m_rectWorking;
115 /// <summary>
116 /// Initializes a new instance of the <see cref="UCAlarmLamp"/> class.
117 /// </summary>
118 public UCAlarmLamp()
119 {
120 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
121 this.SetStyle(ControlStyles.DoubleBuffer, true);
122 this.SetStyle(ControlStyles.ResizeRedraw, true);
123 this.SetStyle(ControlStyles.Selectable, true);
124 this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
125 this.SetStyle(ControlStyles.UserPaint, true);
126 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
127 this.SizeChanged += UCAlarmLamp_SizeChanged;
128 this.Size = new Size(50, 50);
129 timer = new Timer();
130 timer.Interval = 200;
131 timer.Tick += timer_Tick;
132 }
133
134 /// <summary>
135 /// Handles the SizeChanged event of the UCAlarmLamp control.
136 /// </summary>
137 /// <param name="sender">The source of the event.</param>
138 /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
139 void UCAlarmLamp_SizeChanged(object sender, EventArgs e)
140 {
141 m_rectWorking = new Rectangle(10, 0, this.Width - 20, this.Height);
142 }
143 /// <summary>
144 /// Handles the Tick event of the timer control.
145 /// </summary>
146 /// <param name="sender">The source of the event.</param>
147 /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
148 void timer_Tick(object sender, EventArgs e)
149 {
150 intColorIndex++;
151 if (intColorIndex >= lampColor.Length)
152 intColorIndex = 0;
153 Refresh();
154 }
155 /// <summary>
156 /// 引發 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
157 /// </summary>
158 /// <param name="e">包含事件資料的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
159 protected override void OnPaint(PaintEventArgs e)
160 {
161 base.OnPaint(e);
162 var g = e.Graphics;
163 g.SetGDIHigh();
164
165 Color c1 = lampColor[intColorIndex];
166 GraphicsPath path = new GraphicsPath();
167 path.AddLine(new Point(m_rectWorking.Left, m_rectWorking.Bottom), new Point(m_rectWorking.Left, m_rectWorking.Top + m_rectWorking.Width));
168 path.AddArc(new Rectangle(m_rectWorking.Left, m_rectWorking.Top, m_rectWorking.Width, m_rectWorking.Width), 180f, 180f);
169 path.AddLine(new Point(m_rectWorking.Right, m_rectWorking.Top + m_rectWorking.Width), new Point(m_rectWorking.Right, m_rectWorking.Bottom));
170 path.CloseAllFigures();
171 g.FillPath(new SolidBrush(c1), path);
172
173 g.FillRectangle(new SolidBrush(lampstand), new Rectangle(5, m_rectWorking.Bottom - 19, this.Width - 10, 10));
174 g.FillRectangle(new SolidBrush(lampstand), new Rectangle(0, m_rectWorking.Bottom - 10, this.Width, 10));
175 }
176 }
177 }
複制