前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
麻烦博客下方点个【推荐】,谢谢
NuGet
Install-Package HZH_Controls
目录
https://blog.csdn.net/kwwwvagaa/article/details/100586547
用处及效果
准备工作
使用GDI+画的,用到了三角函数,如果不了解可以先行百度
开始
添加一个类UCConduit,继承UserControl
添加几个属性
1 /// <summary>
2 /// The conduit style
3 /// </summary>
4 private ConduitStyle conduitStyle = ConduitStyle.Horizontal_None_None;
5
6 /// <summary>
7 /// Gets or sets the conduit style.
8 /// </summary>
9 /// <value>The conduit style.</value>
10 [Description("样式"), Category("自定义")]
11 public ConduitStyle ConduitStyle
12 {
13 get { return conduitStyle; }
14 set
15 {
16 string strOld = conduitStyle.ToString().Substring(0, 1);
17 string strNew = value.ToString().Substring(0, 1);
18 conduitStyle = value;
19 if (strOld != strNew)
20 {
21 this.Size = new Size(this.Size.Height, this.Size.Width);
22 }
23 Refresh();
24 }
25 }
26
27 /// <summary>
28 /// The conduit color
29 /// </summary>
30 private Color conduitColor = Color.FromArgb(255, 77, 59);
31 [Description("颜色"), Category("自定义")]
32 /// <summary>
33 /// Gets or sets the color of the conduit.
34 /// </summary>
35 /// <value>The color of the conduit.</value>
36 public Color ConduitColor
37 {
38 get { return conduitColor; }
39 set
40 {
41 conduitColor = value;
42 Refresh();
43 }
44 }
45
46 /// <summary>
47 /// The liquid color
48 /// </summary>
49 private Color liquidColor = Color.FromArgb(3, 169, 243);
50
51 /// <summary>
52 /// Gets or sets the color of the liquid.
53 /// </summary>
54 /// <value>The color of the liquid.</value>
55 [Description("液体颜色"), Category("自定义")]
56 public Color LiquidColor
57 {
58 get { return liquidColor; }
59 set
60 {
61 liquidColor = value;
62 if (liquidDirection != Conduit.LiquidDirection.None)
63 Refresh();
64 }
65 }
66
67 /// <summary>
68 /// The liquid direction
69 /// </summary>
70 private LiquidDirection liquidDirection = LiquidDirection.Forward;
71
72 /// <summary>
73 /// Gets or sets the liquid direction.
74 /// </summary>
75 /// <value>The liquid direction.</value>
76 [Description("液体流动方向"), Category("自定义")]
77 public LiquidDirection LiquidDirection
78 {
79 get { return liquidDirection; }
80 set
81 {
82 liquidDirection = value;
83 Refresh();
84 }
85 }
86
87 /// <summary>
88 /// The liquid speed
89 /// </summary>
90 private int liquidSpeed = 100;
91
92 /// <summary>
93 /// 液体流速,越小,速度越快Gets or sets the liquid speed.
94 /// </summary>
95 /// <value>The liquid speed.</value>
96 [Description("液体流速,越小,速度越快"), Category("自定义")]
97 public int LiquidSpeed
98 {
99 get { return liquidSpeed; }
100 set
101 {
102 if (value <= 0)
103 return;
104 liquidSpeed = value;
105 m_timer.Interval = value;
106 }
107 }
108
109 /// <summary>
110 /// The int pen width
111 /// </summary>
112 int intPenWidth = 0;
113
114 /// <summary>
115 /// The int line left
116 /// </summary>
117 int intLineLeft = 0;
118 /// <summary>
119 /// The m timer
120 /// </summary>
121 Timer m_timer;
根据参数设置重绘
1 /// <summary>
2 /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
3 /// </summary>
4 /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
5 protected override void OnPaint(PaintEventArgs e)
6 {
7 base.OnPaint(e);
8 Graphics g = e.Graphics;
9
10 List<ArcEntity> lstArcs = new List<ArcEntity>();
11
12 GraphicsPath path = new GraphicsPath();
13 GraphicsPath linePath = new GraphicsPath();
14 switch (conduitStyle)
15 {
16 #region H English:H
17 case ConduitStyle.Horizontal_None_None:
18 path.AddLines(new PointF[]
19 {
20 new PointF(0, 0),
21 new PointF(this.ClientRectangle.Right, 0),
22 new PointF(this.ClientRectangle.Right, this.Height),
23 new PointF(0, this.Height)
24 });
25 path.CloseAllFigures();
26 linePath.AddLine(0, this.Height / 2, this.Width, this.Height / 2);
27 break;
28 case ConduitStyle.Horizontal_Up_None:
29 path.AddLines(new PointF[]
30 {
31 new PointF(0, 0),
32 new PointF(this.ClientRectangle.Right, 0),
33 new PointF(this.ClientRectangle.Right, this.Height),
34 new PointF(0+intPenWidth, this.Height)
35 });
36 path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
37 path.CloseAllFigures();
38
39 linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
40 linePath.AddLine(intPenWidth, this.Height / 2, this.Width, this.Height / 2);
41
42 lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
43 break;
44 case ConduitStyle.Horizontal_Down_None:
45 path.AddLines(new PointF[]
46 {
47 new PointF(intPenWidth, 0),
48 new PointF(this.ClientRectangle.Right, 0),
49 new PointF(this.ClientRectangle.Right, this.Height),
50 new PointF(0, this.Height)
51 });
52 path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
53 path.CloseAllFigures();
54
55 linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
56 linePath.AddLine(intPenWidth + 1, this.Height / 2, this.Width, this.Height / 2);
57
58 lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
59 break;
60 case ConduitStyle.Horizontal_None_Up:
61 path.AddLines(new PointF[]
62 {
63 new PointF(this.ClientRectangle.Right-intPenWidth, this.Height),
64 new PointF(0, this.Height),
65 new PointF(0, 0),
66 new PointF(this.ClientRectangle.Right-intPenWidth, 0)
67 });
68 path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
69 path.CloseAllFigures();
70
71 linePath.AddLine(0, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
72 linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
73
74 lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
75 break;
76 case ConduitStyle.Horizontal_None_Down:
77 path.AddLines(new PointF[]
78 {
79 new PointF(this.ClientRectangle.Right, this.Height),
80 new PointF(0, this.Height),
81 new PointF(0, 0),
82 new PointF(this.ClientRectangle.Right-intPenWidth, 0)
83 });
84 path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
85 path.CloseAllFigures();
86
87 linePath.AddLine(0, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
88 linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
89
90 lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
91 break;
92 case ConduitStyle.Horizontal_Down_Up:
93 path.AddLine(new Point(intPenWidth, 0), new Point(this.Width, 0));
94 path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
95 path.AddLine(new Point(this.Width - intPenWidth, this.Height), new Point(0, this.Height));
96 path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
97 path.CloseAllFigures();
98
99 linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
100 //linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
101 linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
102
103 lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
104 lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
105 break;
106 case ConduitStyle.Horizontal_Up_Down:
107 path.AddLine(new Point(0, 0), new Point(this.Width - intPenWidth, 0));
108 path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
109 path.AddLine(new Point(this.Width, this.Height), new Point(intPenWidth, this.Height));
110 path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
111 path.CloseAllFigures();
112
113 linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
114 linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
115 linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
116
117 lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
118 lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
119 break;
120 case ConduitStyle.Horizontal_Up_Up:
121 path.AddLine(new Point(0, 0), new Point(this.Width, 0));
122 path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
123 path.AddLine(new Point(this.Width - intPenWidth, this.Height), new Point(intPenWidth, this.Height));
124 path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
125 path.CloseAllFigures();
126
127 linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
128 //linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
129 linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
130
131 lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
132 lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
133 break;
134 case ConduitStyle.Horizontal_Down_Down:
135 path.AddLine(new Point(intPenWidth, 0), new Point(this.Width - intPenWidth, 0));
136 path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
137 path.AddLine(new Point(this.Width, this.Height), new Point(0, this.Height));
138 path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
139 path.CloseAllFigures();
140
141 linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
142 linePath.AddLine(intPenWidth + 1, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
143 linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
144
145 lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
146 lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
147 break;
148 #endregion
149
150 #region V English:V
151 case ConduitStyle.Vertical_None_None:
152 path.AddLines(new PointF[]
153 {
154 new PointF(0, 0),
155 new PointF(this.ClientRectangle.Right, 0),
156 new PointF(this.ClientRectangle.Right, this.Height),
157 new PointF(0, this.Height)
158 });
159 path.CloseAllFigures();
160 linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height);
161 break;
162 case ConduitStyle.Vertical_Left_None:
163 path.AddLines(new PointF[]
164 {
165 new PointF(this.ClientRectangle.Right, intPenWidth),
166 new PointF(this.ClientRectangle.Right, this.Height),
167 new PointF(0, this.Height),
168 new PointF(0, 0)
169 });
170 path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
171 path.CloseAllFigures();
172
173 linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
174 linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height);
175
176 lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
177 break;
178 case ConduitStyle.Vertical_Right_None:
179 path.AddLines(new PointF[]
180 {
181 new PointF(this.ClientRectangle.Right, 0),
182 new PointF(this.ClientRectangle.Right, this.Height),
183 new PointF(0, this.Height),
184 new PointF(0, intPenWidth)
185 });
186 path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
187 path.CloseAllFigures();
188
189 linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
190 linePath.AddLine(intPenWidth / 2, intPenWidth + 1, intPenWidth / 2, this.Height);
191
192 lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
193 break;
194 case ConduitStyle.Vertical_None_Left:
195 path.AddLines(new PointF[]
196 {
197 new PointF(0, this.Height),
198 new PointF(0, 0),
199 new PointF(this.ClientRectangle.Right, 0),
200 new PointF(this.ClientRectangle.Right, this.Height-intPenWidth),
201 });
202 path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
203 path.CloseAllFigures();
204
205 linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height - intPenWidth);
206 linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
207
208 lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
209 break;
210 case ConduitStyle.Vertical_None_Right:
211 path.AddLines(new PointF[]
212 {
213 new PointF(0, this.Height-intPenWidth),
214 new PointF(0, 0),
215 new PointF(this.ClientRectangle.Right, 0),
216 new PointF(this.ClientRectangle.Right, this.Height),
217 });
218 path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
219 path.CloseAllFigures();
220
221 linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height - intPenWidth - 1);
222 linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
223
224 lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
225 break;
226 case ConduitStyle.Vertical_Left_Right:
227 path.AddLine(this.Width, intPenWidth, this.Width, this.Height);
228 path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
229 path.AddLine(0, this.Height - intPenWidth, 0, 0);
230 path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
231 path.CloseAllFigures();
232
233 linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
234 //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
235 linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
236
237 lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
238 lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
239 break;
240 case ConduitStyle.Vertical_Right_Left:
241 path.AddLine(this.Width, 0, this.Width, this.Height - intPenWidth);
242 path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
243 path.AddLine(0, this.Height, 0, intPenWidth);
244 path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
245 path.CloseAllFigures();
246
247 linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
248 //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
249 linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
250
251 lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
252 lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
253 break;
254 case ConduitStyle.Vertical_Left_Left:
255 path.AddLine(this.Width, intPenWidth, this.Width, this.Height - intPenWidth);
256 path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
257 path.AddLine(0, this.Height, 0, 0);
258 path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
259 path.CloseAllFigures();
260
261 linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
262 //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
263 linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
264
265 lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
266 lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
267 break;
268 case ConduitStyle.Vertical_Right_Right:
269 path.AddLine(this.Width, 0, this.Width, this.Height);
270 path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
271 path.AddLine(0, this.Height - intPenWidth, 0, intPenWidth);
272 path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
273 path.CloseAllFigures();
274
275 linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
276 //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
277 linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 180, -91);
278
279 lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
280 lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
281 break;
282 #endregion
283 }
284 g.FillPath(new SolidBrush(conduitColor), path);
285
286 //渐变色
287 int intCount = intPenWidth / 2 / 4;
288 int intSplit = (255 - 100) / intCount;
289 for (int i = 0; i < intCount; i++)
290 {
291 int _penWidth = intPenWidth / 2 - 4 * i;
292 if (_penWidth <= 0)
293 _penWidth = 1;
294 g.DrawPath(new Pen(new SolidBrush(Color.FromArgb(40, Color.White.R, Color.White.G, Color.White.B)), _penWidth), linePath);
295 if (_penWidth == 1)
296 break;
297 }
298
299 g.SetGDIHigh();
300 //使用抗锯齿画圆角
301 foreach (var item in lstArcs)
302 {
303 g.DrawArc(new Pen(new SolidBrush(this.BackColor)), item.rect, item.startAngle, item.sweepAngle);
304 }
305
306 //液体流动
307 if (LiquidDirection != Conduit.LiquidDirection.None)
308 {
309 Pen p = new Pen(new SolidBrush(liquidColor), 4);
310 p.DashPattern = new float[] { 6, 6 };
311 p.DashOffset = intLineLeft * (LiquidDirection == Conduit.LiquidDirection.Forward ? -1 : 1);
312 g.DrawPath(p, linePath);
313 }
314 }
一个记录圆角的类
1 /// <summary>
2 /// Class ArcEntity.
3 /// </summary>
4 class ArcEntity
5 {
6 /// <summary>
7 /// Gets or sets the rect.
8 /// </summary>
9 /// <value>The rect.</value>
10 public Rectangle rect { get; set; }
11 /// <summary>
12 /// Gets or sets the start angle.
13 /// </summary>
14 /// <value>The start angle.</value>
15 public float startAngle { get; set; }
16 /// <summary>
17 /// Gets or sets the sweep angle.
18 /// </summary>
19 /// <value>The sweep angle.</value>
20 public float sweepAngle { get; set; }
21 }
2个枚举
1 /// <summary>
2 /// Enum LiquidDirection
3 /// </summary>
4 public enum LiquidDirection
5 {
6 /// <summary>
7 /// The none
8 /// </summary>
9 None,
10 /// <summary>
11 /// The forward
12 /// </summary>
13 Forward,
14 /// <summary>
15 /// The backward
16 /// </summary>
17 Backward
18 }
19
20 /// <summary>
21 /// 管道样式Enum ConduitStyle
22 /// </summary>
23 public enum ConduitStyle
24 {
25 /// <summary>
26 /// 直线 The horizontal none none
27 /// </summary>
28 Horizontal_None_None,
29 /// <summary>
30 /// 左上The horizontal up none
31 /// </summary>
32 Horizontal_Up_None,
33 /// <summary>
34 /// 左下The horizontal down none
35 /// </summary>
36 Horizontal_Down_None,
37 /// <summary>
38 /// 右上The horizontal none up
39 /// </summary>
40 Horizontal_None_Up,
41 /// <summary>
42 /// 右下The horizontal none down
43 /// </summary>
44 Horizontal_None_Down,
45 /// <summary>
46 /// 左下右上The horizontal down up
47 /// </summary>
48 Horizontal_Down_Up,
49 /// <summary>
50 /// 左上右下The horizontal up down
51 /// </summary>
52 Horizontal_Up_Down,
53 /// <summary>
54 /// 左上,右上The horizontal up up
55 /// </summary>
56 Horizontal_Up_Up,
57 /// <summary>
58 /// 左下右下The horizontal down down
59 /// </summary>
60 Horizontal_Down_Down,
61
62 /// <summary>
63 /// 竖线The vertical none none
64 /// </summary>
65 Vertical_None_None,
66 /// <summary>
67 /// 上左The vertical left none
68 /// </summary>
69 Vertical_Left_None,
70 /// <summary>
71 /// 上右The vertical right none
72 /// </summary>
73 Vertical_Right_None,
74 /// <summary>
75 /// 下左The vertical none left
76 /// </summary>
77 Vertical_None_Left,
78 /// <summary>
79 /// 下右The vertical none right
80 /// </summary>
81 Vertical_None_Right,
82 /// <summary>
83 /// 上左下右The vertical left right
84 /// </summary>
85 Vertical_Left_Right,
86 /// <summary>
87 /// 上右下左The vertical right left
88 /// </summary>
89 Vertical_Right_Left,
90 /// <summary>
91 /// 上左下左The vertical left left
92 /// </summary>
93 Vertical_Left_Left,
94 /// <summary>
95 /// 上右下右The vertical right left
96 /// </summary>
97 Vertical_Right_Right,
98 }
重点讲解来了,
重绘的时候,先填充底色,并且记录下中心线path,和圆角
填充底色后,画中间的渐变色
然后设置g为抗锯齿模式,把圆角重画一遍,就没有锯齿感了
然后根据中心线,画液体就可以了
完整代码
// ***********************************************************************
// Assembly : HZH_Controls
// Created : 2019-09-04
//
// ***********************************************************************
// <copyright file="UCConduit.cs">
// Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:[email protected]
// </copyright>
//
// Blog: https://www.cnblogs.com/bfyx
// GitHub:https://github.com/kwwwvagaa/NetWinformControl
// gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
//
// If you use this code, please keep this note.
// ***********************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
namespace HZH_Controls.Controls.Conduit
{
/// <summary>
/// Class UCConduit.
/// Implements the <see cref="System.Windows.Forms.UserControl" />
/// </summary>
/// <seealso cref="System.Windows.Forms.UserControl" />
public class UCConduit : UserControl
{
/// <summary>
/// The conduit style
/// </summary>
private ConduitStyle conduitStyle = ConduitStyle.Horizontal_None_None;
/// <summary>
/// Gets or sets the conduit style.
/// </summary>
/// <value>The conduit style.</value>
[Description("样式"), Category("自定义")]
public ConduitStyle ConduitStyle
{
get { return conduitStyle; }
set
{
string strOld = conduitStyle.ToString().Substring(0, 1);
string strNew = value.ToString().Substring(0, 1);
conduitStyle = value;
if (strOld != strNew)
{
this.Size = new Size(this.Size.Height, this.Size.Width);
}
Refresh();
}
}
/// <summary>
/// The conduit color
/// </summary>
private Color conduitColor = Color.FromArgb(255, 77, 59);
[Description("颜色"), Category("自定义")]
/// <summary>
/// Gets or sets the color of the conduit.
/// </summary>
/// <value>The color of the conduit.</value>
public Color ConduitColor
{
get { return conduitColor; }
set
{
conduitColor = value;
Refresh();
}
}
/// <summary>
/// The liquid color
/// </summary>
private Color liquidColor = Color.FromArgb(3, 169, 243);
/// <summary>
/// Gets or sets the color of the liquid.
/// </summary>
/// <value>The color of the liquid.</value>
[Description("液体颜色"), Category("自定义")]
public Color LiquidColor
{
get { return liquidColor; }
set
{
liquidColor = value;
if (liquidDirection != Conduit.LiquidDirection.None)
Refresh();
}
}
/// <summary>
/// The liquid direction
/// </summary>
private LiquidDirection liquidDirection = LiquidDirection.Forward;
/// <summary>
/// Gets or sets the liquid direction.
/// </summary>
/// <value>The liquid direction.</value>
[Description("液体流动方向"), Category("自定义")]
public LiquidDirection LiquidDirection
{
get { return liquidDirection; }
set
{
liquidDirection = value;
Refresh();
}
}
/// <summary>
/// The liquid speed
/// </summary>
private int liquidSpeed = 100;
/// <summary>
/// 液体流速,越小,速度越快Gets or sets the liquid speed.
/// </summary>
/// <value>The liquid speed.</value>
[Description("液体流速,越小,速度越快"), Category("自定义")]
public int LiquidSpeed
{
get { return liquidSpeed; }
set
{
if (value <= 0)
return;
liquidSpeed = value;
m_timer.Interval = value;
}
}
/// <summary>
/// The int pen width
/// </summary>
int intPenWidth = 0;
/// <summary>
/// The int line left
/// </summary>
int intLineLeft = 0;
/// <summary>
/// The m timer
/// </summary>
Timer m_timer;
/// <summary>
/// Initializes a new instance of the <see cref="UCConduit"/> class.
/// </summary>
public UCConduit()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
this.SetStyle(ControlStyles.DoubleBuffer, true);
this.SetStyle(ControlStyles.ResizeRedraw, true);
this.SetStyle(ControlStyles.Selectable, true);
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
this.SetStyle(ControlStyles.UserPaint, true);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.SizeChanged += UCConduit_SizeChanged;
this.Size = new Size(200, 50);
m_timer = new Timer();
m_timer.Interval = 100;
m_timer.Tick += timer_Tick;
m_timer.Enabled = true;
}
/// <summary>
/// Handles the Tick event of the timer control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
void timer_Tick(object sender, EventArgs e)
{
intLineLeft += 2;
if (intLineLeft > 12)
intLineLeft = 0;
Refresh();
}
/// <summary>
/// Handles the SizeChanged event of the UCConduit control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
void UCConduit_SizeChanged(object sender, EventArgs e)
{
intPenWidth = conduitStyle.ToString().StartsWith("H") ? this.Height : this.Width;
}
/// <summary>
/// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
/// </summary>
/// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
Graphics g = e.Graphics;
List<ArcEntity> lstArcs = new List<ArcEntity>();
GraphicsPath path = new GraphicsPath();
GraphicsPath linePath = new GraphicsPath();
switch (conduitStyle)
{
#region H English:H
case ConduitStyle.Horizontal_None_None:
path.AddLines(new PointF[]
{
new PointF(0, 0),
new PointF(this.ClientRectangle.Right, 0),
new PointF(this.ClientRectangle.Right, this.Height),
new PointF(0, this.Height)
});
path.CloseAllFigures();
linePath.AddLine(0, this.Height / 2, this.Width, this.Height / 2);
break;
case ConduitStyle.Horizontal_Up_None:
path.AddLines(new PointF[]
{
new PointF(0, 0),
new PointF(this.ClientRectangle.Right, 0),
new PointF(this.ClientRectangle.Right, this.Height),
new PointF(0+intPenWidth, this.Height)
});
path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
path.CloseAllFigures();
linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
linePath.AddLine(intPenWidth, this.Height / 2, this.Width, this.Height / 2);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
break;
case ConduitStyle.Horizontal_Down_None:
path.AddLines(new PointF[]
{
new PointF(intPenWidth, 0),
new PointF(this.ClientRectangle.Right, 0),
new PointF(this.ClientRectangle.Right, this.Height),
new PointF(0, this.Height)
});
path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
path.CloseAllFigures();
linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
linePath.AddLine(intPenWidth + 1, this.Height / 2, this.Width, this.Height / 2);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
break;
case ConduitStyle.Horizontal_None_Up:
path.AddLines(new PointF[]
{
new PointF(this.ClientRectangle.Right-intPenWidth, this.Height),
new PointF(0, this.Height),
new PointF(0, 0),
new PointF(this.ClientRectangle.Right-intPenWidth, 0)
});
path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
path.CloseAllFigures();
linePath.AddLine(0, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
break;
case ConduitStyle.Horizontal_None_Down:
path.AddLines(new PointF[]
{
new PointF(this.ClientRectangle.Right, this.Height),
new PointF(0, this.Height),
new PointF(0, 0),
new PointF(this.ClientRectangle.Right-intPenWidth, 0)
});
path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
path.CloseAllFigures();
linePath.AddLine(0, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
break;
case ConduitStyle.Horizontal_Down_Up:
path.AddLine(new Point(intPenWidth, 0), new Point(this.Width, 0));
path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
path.AddLine(new Point(this.Width - intPenWidth, this.Height), new Point(0, this.Height));
path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
path.CloseAllFigures();
linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
//linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
break;
case ConduitStyle.Horizontal_Up_Down:
path.AddLine(new Point(0, 0), new Point(this.Width - intPenWidth, 0));
path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
path.AddLine(new Point(this.Width, this.Height), new Point(intPenWidth, this.Height));
path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
path.CloseAllFigures();
linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
break;
case ConduitStyle.Horizontal_Up_Up:
path.AddLine(new Point(0, 0), new Point(this.Width, 0));
path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
path.AddLine(new Point(this.Width - intPenWidth, this.Height), new Point(intPenWidth, this.Height));
path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
path.CloseAllFigures();
linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
//linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
break;
case ConduitStyle.Horizontal_Down_Down:
path.AddLine(new Point(intPenWidth, 0), new Point(this.Width - intPenWidth, 0));
path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
path.AddLine(new Point(this.Width, this.Height), new Point(0, this.Height));
path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
path.CloseAllFigures();
linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
linePath.AddLine(intPenWidth + 1, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
break;
#endregion
#region V English:V
case ConduitStyle.Vertical_None_None:
path.AddLines(new PointF[]
{
new PointF(0, 0),
new PointF(this.ClientRectangle.Right, 0),
new PointF(this.ClientRectangle.Right, this.Height),
new PointF(0, this.Height)
});
path.CloseAllFigures();
linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height);
break;
case ConduitStyle.Vertical_Left_None:
path.AddLines(new PointF[]
{
new PointF(this.ClientRectangle.Right, intPenWidth),
new PointF(this.ClientRectangle.Right, this.Height),
new PointF(0, this.Height),
new PointF(0, 0)
});
path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
path.CloseAllFigures();
linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
break;
case ConduitStyle.Vertical_Right_None:
path.AddLines(new PointF[]
{
new PointF(this.ClientRectangle.Right, 0),
new PointF(this.ClientRectangle.Right, this.Height),
new PointF(0, this.Height),
new PointF(0, intPenWidth)
});
path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
path.CloseAllFigures();
linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
linePath.AddLine(intPenWidth / 2, intPenWidth + 1, intPenWidth / 2, this.Height);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
break;
case ConduitStyle.Vertical_None_Left:
path.AddLines(new PointF[]
{
new PointF(0, this.Height),
new PointF(0, 0),
new PointF(this.ClientRectangle.Right, 0),
new PointF(this.ClientRectangle.Right, this.Height-intPenWidth),
});
path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
path.CloseAllFigures();
linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height - intPenWidth);
linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
break;
case ConduitStyle.Vertical_None_Right:
path.AddLines(new PointF[]
{
new PointF(0, this.Height-intPenWidth),
new PointF(0, 0),
new PointF(this.ClientRectangle.Right, 0),
new PointF(this.ClientRectangle.Right, this.Height),
});
path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
path.CloseAllFigures();
linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height - intPenWidth - 1);
linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
break;
case ConduitStyle.Vertical_Left_Right:
path.AddLine(this.Width, intPenWidth, this.Width, this.Height);
path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
path.AddLine(0, this.Height - intPenWidth, 0, 0);
path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
path.CloseAllFigures();
linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
//linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
break;
case ConduitStyle.Vertical_Right_Left:
path.AddLine(this.Width, 0, this.Width, this.Height - intPenWidth);
path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
path.AddLine(0, this.Height, 0, intPenWidth);
path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
path.CloseAllFigures();
linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
//linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
break;
case ConduitStyle.Vertical_Left_Left:
path.AddLine(this.Width, intPenWidth, this.Width, this.Height - intPenWidth);
path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
path.AddLine(0, this.Height, 0, 0);
path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
path.CloseAllFigures();
linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
//linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
break;
case ConduitStyle.Vertical_Right_Right:
path.AddLine(this.Width, 0, this.Width, this.Height);
path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
path.AddLine(0, this.Height - intPenWidth, 0, intPenWidth);
path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
path.CloseAllFigures();
linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
//linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 180, -91);
lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
break;
#endregion
}
g.FillPath(new SolidBrush(conduitColor), path);
//渐变色
int intCount = intPenWidth / 2 / 4;
int intSplit = (255 - 100) / intCount;
for (int i = 0; i < intCount; i++)
{
int _penWidth = intPenWidth / 2 - 4 * i;
if (_penWidth <= 0)
_penWidth = 1;
g.DrawPath(new Pen(new SolidBrush(Color.FromArgb(40, Color.White.R, Color.White.G, Color.White.B)), _penWidth), linePath);
if (_penWidth == 1)
break;
}
g.SetGDIHigh();
//使用抗锯齿画圆角
foreach (var item in lstArcs)
{
g.DrawArc(new Pen(new SolidBrush(this.BackColor)), item.rect, item.startAngle, item.sweepAngle);
}
//液体流动
if (LiquidDirection != Conduit.LiquidDirection.None)
{
Pen p = new Pen(new SolidBrush(liquidColor), 4);
p.DashPattern = new float[] { 6, 6 };
p.DashOffset = intLineLeft * (LiquidDirection == Conduit.LiquidDirection.Forward ? -1 : 1);
g.DrawPath(p, linePath);
}
}
/// <summary>
/// Class ArcEntity.
/// </summary>
class ArcEntity
{
/// <summary>
/// Gets or sets the rect.
/// </summary>
/// <value>The rect.</value>
public Rectangle rect { get; set; }
/// <summary>
/// Gets or sets the start angle.
/// </summary>
/// <value>The start angle.</value>
public float startAngle { get; set; }
/// <summary>
/// Gets or sets the sweep angle.
/// </summary>
/// <value>The sweep angle.</value>
public float sweepAngle { get; set; }
}
}
/// <summary>
/// Enum LiquidDirection
/// </summary>
public enum LiquidDirection
{
/// <summary>
/// The none
/// </summary>
None,
/// <summary>
/// The forward
/// </summary>
Forward,
/// <summary>
/// The backward
/// </summary>
Backward
}
/// <summary>
/// 管道样式Enum ConduitStyle
/// </summary>
public enum ConduitStyle
{
/// <summary>
/// 直线 The horizontal none none
/// </summary>
Horizontal_None_None,
/// <summary>
/// 左上The horizontal up none
/// </summary>
Horizontal_Up_None,
/// <summary>
/// 左下The horizontal down none
/// </summary>
Horizontal_Down_None,
/// <summary>
/// 右上The horizontal none up
/// </summary>
Horizontal_None_Up,
/// <summary>
/// 右下The horizontal none down
/// </summary>
Horizontal_None_Down,
/// <summary>
/// 左下右上The horizontal down up
/// </summary>
Horizontal_Down_Up,
/// <summary>
/// 左上右下The horizontal up down
/// </summary>
Horizontal_Up_Down,
/// <summary>
/// 左上,右上The horizontal up up
/// </summary>
Horizontal_Up_Up,
/// <summary>
/// 左下右下The horizontal down down
/// </summary>
Horizontal_Down_Down,
/// <summary>
/// 竖线The vertical none none
/// </summary>
Vertical_None_None,
/// <summary>
/// 上左The vertical left none
/// </summary>
Vertical_Left_None,
/// <summary>
/// 上右The vertical right none
/// </summary>
Vertical_Right_None,
/// <summary>
/// 下左The vertical none left
/// </summary>
Vertical_None_Left,
/// <summary>
/// 下右The vertical none right
/// </summary>
Vertical_None_Right,
/// <summary>
/// 上左下右The vertical left right
/// </summary>
Vertical_Left_Right,
/// <summary>
/// 上右下左The vertical right left
/// </summary>
Vertical_Right_Left,
/// <summary>
/// 上左下左The vertical left left
/// </summary>
Vertical_Left_Left,
/// <summary>
/// 上右下右The vertical right left
/// </summary>
Vertical_Right_Right,
}
}
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧