(六十三)c#Winform自定义控件-箭头(工业)

2022-10-16,,,

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

github:https://github.com/kwwwvagaa/netwinformcontrol

码云:

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 

麻烦博客下方点个【推荐】,谢谢

nuget

install-package hzh_controls

目录

用处及效果

准备工作

依然用gdi+,请自行百度了解

开始

添加一个类ucarrow,继承usercontrol

添加枚举,控制方向

 1 /// <summary>
 2     /// enum arrowdirection
 3     /// </summary>
 4     public enum arrowdirection
 5     {
 6         /// <summary>
 7         /// the left
 8         /// </summary>
 9         left,
10         /// <summary>
11         /// the right
12         /// </summary>
13         right,
14         /// <summary>
15         /// the top
16         /// </summary>
17         top,
18         /// <summary>
19         /// the bottom
20         /// </summary>
21         bottom,
22         /// <summary>
23         /// the left right
24         /// </summary>
25         left_right,
26         /// <summary>
27         /// the top bottom
28         /// </summary>
29         top_bottom
30     }

一些属性

  1  /// <summary>
  2         /// the arrow color
  3         /// </summary>
  4         private color arrowcolor = color.fromargb(255, 77, 59);
  5 
  6         /// <summary>
  7         /// gets or sets the color of the arrow.
  8         /// </summary>
  9         /// <value>the color of the arrow.</value>
 10         [description("箭头颜色"), category("自定义")]
 11         public color arrowcolor
 12         {
 13             get { return arrowcolor; }
 14             set
 15             {
 16                 arrowcolor = value;
 17                 refresh();
 18             }
 19         }
 20 
 21         /// <summary>
 22         /// the border color
 23         /// </summary>
 24         private color? bordercolor = null;
 25 
 26         /// <summary>
 27         /// gets or sets the color of the border.
 28         /// </summary>
 29         /// <value>the color of the border.</value>
 30         [description("箭头边框颜色,为空则无边框"), category("自定义")]
 31         public color? bordercolor
 32         {
 33             get { return bordercolor; }
 34             set
 35             {
 36                 bordercolor = value;
 37                 refresh();
 38             }
 39         }
 40 
 41         /// <summary>
 42         /// the direction
 43         /// </summary>
 44         private arrowdirection direction = arrowdirection.right;
 45 
 46         /// <summary>
 47         /// gets or sets the direction.
 48         /// </summary>
 49         /// <value>the direction.</value>
 50         [description("箭头方向"), category("自定义")]
 51         public arrowdirection direction
 52         {
 53             get { return direction; }
 54             set
 55             {
 56                 direction = value;
 57                 resetpath();
 58                 refresh();
 59             }
 60         }
 61         /// <summary>
 62         /// 获取或设置控件显示的文字的字体。
 63         /// </summary>
 64         /// <value>the font.</value>
 65         /// <permissionset>
 66         ///   <ipermission class="system.security.permissions.environmentpermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
 67         ///   <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
 68         ///   <ipermission class="system.security.permissions.securitypermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" flags="unmanagedcode, controlevidence" />
 69         ///   <ipermission class="system.diagnostics.performancecounterpermission, system, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
 70         /// </permissionset>
 71         public override font font
 72         {
 73             get
 74             {
 75                 return base.font;
 76             }
 77             set
 78             {
 79                 base.font = value;
 80                 refresh();
 81             }
 82         }
 83         /// <summary>
 84         /// 获取或设置控件的前景色。
 85         /// </summary>
 86         /// <value>the color of the fore.</value>
 87         /// <permissionset>
 88         ///   <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
 89         /// </permissionset>
 90         public override color forecolor
 91         {
 92             get
 93             {
 94                 return base.forecolor;
 95             }
 96             set
 97             {
 98                 base.forecolor = value;
 99                 refresh();
100             }
101         }
102         /// <summary>
103         /// the text
104         /// </summary>
105         private string text;
106         /// <summary>
107         /// gets or sets the text.
108         /// </summary>
109         /// <value>the text.</value>
110         [bindable(true)]
111         [browsable(true)]
112         [designerserializationvisibility(designerserializationvisibility.visible)]
113         [editorbrowsable(editorbrowsablestate.always)]
114         [localizable(true)]
115         [description("箭头文字"), category("自定义")]
116         public override string text
117         {
118             get
119             {
120                 return text;
121             }
122             set
123             {
124                 text = value;
125                 refresh();
126             }
127         }
128         /// <summary>
129         /// the m path
130         /// </summary>
131         graphicspath m_path;

根据方向和大小设置path

 1   private void resetpath()
 2         {
 3             point[] ps = null;
 4             switch (direction)
 5             {
 6                 case arrowdirection.left:
 7                     ps = new point[] 
 8                     { 
 9                         new point(0,this.height/2),
10                         new point(40,0),
11                         new point(40,this.height/4),
12                         new point(this.width-1,this.height/4),
13                         new point(this.width-1,this.height-this.height/4),
14                         new point(40,this.height-this.height/4),
15                         new point(40,this.height),
16                         new point(0,this.height/2)
17                     };
18                     break;
19                 case arrowdirection.right:
20                     ps = new point[] 
21                     {
22                         new point(0,this.height/4),
23                         new point(this.width-40,this.height/4),
24                         new point(this.width-40,0),
25                         new point(this.width-1,this.height/2),
26                         new point(this.width-40,this.height),
27                         new point(this.width-40,this.height-this.height/4),                      
28                         new point(0,this.height-this.height/4),
29                         new point(0,this.height/4)
30                     };
31                     break;
32                 case arrowdirection.top:
33                     ps = new point[] 
34                     {
35                        new point(this.width/2,0),
36                        new point(this.width,40),
37                        new point(this.width-this.width/4,40),
38                        new point(this.width-this.width/4,this.height-1),
39                        new point(this.width/4,this.height-1),
40                        new point(this.width/4,40),
41                        new point(0,40),
42                        new point(this.width/2,0),
43                     };
44                     break;
45                 case arrowdirection.bottom:
46                     ps = new point[] 
47                     {
48                        new point(this.width-this.width/4,0),
49                        new point(this.width-this.width/4,this.height-40),
50                        new point(this.width,this.height-40),
51                        new point(this.width/2,this.height-1),
52                        new point(0,this.height-40),
53                        new point(this.width/4,this.height-40),
54                        new point(this.width/4,0),
55                        new point(this.width-this.width/4,0),                      
56                     };
57                     break;
58                 case arrowdirection.left_right:
59                     ps = new point[] 
60                     { 
61                         new point(0,this.height/2),
62                         new point(40,0),
63                         new point(40,this.height/4),
64                         new point(this.width-40,this.height/4),
65                         new point(this.width-40,0),
66                         new point(this.width-1,this.height/2),
67                         new point(this.width-40,this.height),
68                         new point(this.width-40,this.height-this.height/4),
69                         new point(40,this.height-this.height/4),
70                         new point(40,this.height),
71                         new point(0,this.height/2),                       
72                     };
73                     break;
74                 case arrowdirection.top_bottom:
75                     ps = new point[] 
76                     {
77                        new point(this.width/2,0),
78                        new point(this.width,40),
79                        new point(this.width-this.width/4,40),
80                        new point(this.width-this.width/4,this.height-40),
81                        new point(this.width,this.height-40),
82                        new point(this.width/2,this.height-1),
83                        new point(0,this.height-40),
84                        new point(this.width/4,this.height-40),
85                        new point(this.width/4,40),
86                        new point(0,40),
87                        new point(this.width/2,0),                      
88                     };
89                     break;
90             }
91             m_path = new graphicspath();
92             m_path.addlines(ps);
93             m_path.closeallfigures();
94         }

重绘

 1   protected override void onpaint(painteventargs e)
 2         {
 3             base.onpaint(e);
 4             var g = e.graphics;
 5             g.setgdihigh();
 6 
 7             g.fillpath(new solidbrush(arrowcolor), m_path);
 8 
 9             if (bordercolor != null && bordercolor != color.empty)
10                 g.drawpath(new pen(new solidbrush(bordercolor.value)), m_path);
11             if (!string.isnullorempty(text))
12             {
13                 var size = g.measurestring(text, font);
14                 g.drawstring(text, font, new solidbrush(forecolor), new pointf((this.width - size.width) / 2, (this.height - size.height) / 2));
15             }
16         }

完整代码

  1 // ***********************************************************************
  2 // assembly         : hzh_controls
  3 // created          : 2019-09-10
  4 //
  5 // ***********************************************************************
  6 // <copyright file="ucarrow.cs">
  7 //     copyright by huang zhenghui(黄正辉) all, qq group:568015492 qq:623128629 email:623128629@qq.com
  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 ucarrow.
 29     /// implements the <see cref="system.windows.forms.usercontrol" />
 30     /// </summary>
 31     /// <seealso cref="system.windows.forms.usercontrol" />
 32     public class ucarrow : usercontrol
 33     {
 34         /// <summary>
 35         /// the arrow color
 36         /// </summary>
 37         private color arrowcolor = color.fromargb(255, 77, 59);
 38 
 39         /// <summary>
 40         /// gets or sets the color of the arrow.
 41         /// </summary>
 42         /// <value>the color of the arrow.</value>
 43         [description("箭头颜色"), category("自定义")]
 44         public color arrowcolor
 45         {
 46             get { return arrowcolor; }
 47             set
 48             {
 49                 arrowcolor = value;
 50                 refresh();
 51             }
 52         }
 53 
 54         /// <summary>
 55         /// the border color
 56         /// </summary>
 57         private color? bordercolor = null;
 58 
 59         /// <summary>
 60         /// gets or sets the color of the border.
 61         /// </summary>
 62         /// <value>the color of the border.</value>
 63         [description("箭头边框颜色,为空则无边框"), category("自定义")]
 64         public color? bordercolor
 65         {
 66             get { return bordercolor; }
 67             set
 68             {
 69                 bordercolor = value;
 70                 refresh();
 71             }
 72         }
 73 
 74         /// <summary>
 75         /// the direction
 76         /// </summary>
 77         private arrowdirection direction = arrowdirection.right;
 78 
 79         /// <summary>
 80         /// gets or sets the direction.
 81         /// </summary>
 82         /// <value>the direction.</value>
 83         [description("箭头方向"), category("自定义")]
 84         public arrowdirection direction
 85         {
 86             get { return direction; }
 87             set
 88             {
 89                 direction = value;
 90                 resetpath();
 91                 refresh();
 92             }
 93         }
 94         /// <summary>
 95         /// 获取或设置控件显示的文字的字体。
 96         /// </summary>
 97         /// <value>the font.</value>
 98         /// <permissionset>
 99         ///   <ipermission class="system.security.permissions.environmentpermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
100         ///   <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
101         ///   <ipermission class="system.security.permissions.securitypermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" flags="unmanagedcode, controlevidence" />
102         ///   <ipermission class="system.diagnostics.performancecounterpermission, system, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
103         /// </permissionset>
104         public override font font
105         {
106             get
107             {
108                 return base.font;
109             }
110             set
111             {
112                 base.font = value;
113                 refresh();
114             }
115         }
116         /// <summary>
117         /// 获取或设置控件的前景色。
118         /// </summary>
119         /// <value>the color of the fore.</value>
120         /// <permissionset>
121         ///   <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
122         /// </permissionset>
123         public override color forecolor
124         {
125             get
126             {
127                 return base.forecolor;
128             }
129             set
130             {
131                 base.forecolor = value;
132                 refresh();
133             }
134         }
135         /// <summary>
136         /// the text
137         /// </summary>
138         private string text;
139         /// <summary>
140         /// gets or sets the text.
141         /// </summary>
142         /// <value>the text.</value>
143         [bindable(true)]
144         [browsable(true)]
145         [designerserializationvisibility(designerserializationvisibility.visible)]
146         [editorbrowsable(editorbrowsablestate.always)]
147         [localizable(true)]
148         [description("箭头文字"), category("自定义")]
149         public override string text
150         {
151             get
152             {
153                 return text;
154             }
155             set
156             {
157                 text = value;
158                 refresh();
159             }
160         }
161         /// <summary>
162         /// the m path
163         /// </summary>
164         graphicspath m_path;
165         /// <summary>
166         /// initializes a new instance of the <see cref="ucarrow"/> class.
167         /// </summary>
168         public ucarrow()
169         {
170             this.setstyle(controlstyles.allpaintinginwmpaint, true);
171             this.setstyle(controlstyles.doublebuffer, true);
172             this.setstyle(controlstyles.resizeredraw, true);
173             this.setstyle(controlstyles.selectable, true);
174             this.setstyle(controlstyles.supportstransparentbackcolor, true);
175             this.setstyle(controlstyles.userpaint, true);
176             this.forecolor = color.white;
177             this.autoscalemode = system.windows.forms.autoscalemode.none;
178             this.sizechanged += ucarrow_sizechanged;
179             this.size = new size(100, 50);
180         }
181 
182         /// <summary>
183         /// handles the sizechanged event of the ucarrow control.
184         /// </summary>
185         /// <param name="sender">the source of the event.</param>
186         /// <param name="e">the <see cref="eventargs"/> instance containing the event data.</param>
187         void ucarrow_sizechanged(object sender, eventargs e)
188         {
189             resetpath();
190         }
191 
192         /// <summary>
193         /// resets the path.
194         /// </summary>
195         private void resetpath()
196         {
197             point[] ps = null;
198             switch (direction)
199             {
200                 case arrowdirection.left:
201                     ps = new point[] 
202                     { 
203                         new point(0,this.height/2),
204                         new point(40,0),
205                         new point(40,this.height/4),
206                         new point(this.width-1,this.height/4),
207                         new point(this.width-1,this.height-this.height/4),
208                         new point(40,this.height-this.height/4),
209                         new point(40,this.height),
210                         new point(0,this.height/2)
211                     };
212                     break;
213                 case arrowdirection.right:
214                     ps = new point[] 
215                     {
216                         new point(0,this.height/4),
217                         new point(this.width-40,this.height/4),
218                         new point(this.width-40,0),
219                         new point(this.width-1,this.height/2),
220                         new point(this.width-40,this.height),
221                         new point(this.width-40,this.height-this.height/4),                      
222                         new point(0,this.height-this.height/4),
223                         new point(0,this.height/4)
224                     };
225                     break;
226                 case arrowdirection.top:
227                     ps = new point[] 
228                     {
229                        new point(this.width/2,0),
230                        new point(this.width,40),
231                        new point(this.width-this.width/4,40),
232                        new point(this.width-this.width/4,this.height-1),
233                        new point(this.width/4,this.height-1),
234                        new point(this.width/4,40),
235                        new point(0,40),
236                        new point(this.width/2,0),
237                     };
238                     break;
239                 case arrowdirection.bottom:
240                     ps = new point[] 
241                     {
242                        new point(this.width-this.width/4,0),
243                        new point(this.width-this.width/4,this.height-40),
244                        new point(this.width,this.height-40),
245                        new point(this.width/2,this.height-1),
246                        new point(0,this.height-40),
247                        new point(this.width/4,this.height-40),
248                        new point(this.width/4,0),
249                        new point(this.width-this.width/4,0),                      
250                     };
251                     break;
252                 case arrowdirection.left_right:
253                     ps = new point[] 
254                     { 
255                         new point(0,this.height/2),
256                         new point(40,0),
257                         new point(40,this.height/4),
258                         new point(this.width-40,this.height/4),
259                         new point(this.width-40,0),
260                         new point(this.width-1,this.height/2),
261                         new point(this.width-40,this.height),
262                         new point(this.width-40,this.height-this.height/4),
263                         new point(40,this.height-this.height/4),
264                         new point(40,this.height),
265                         new point(0,this.height/2),                       
266                     };
267                     break;
268                 case arrowdirection.top_bottom:
269                     ps = new point[] 
270                     {
271                        new point(this.width/2,0),
272                        new point(this.width,40),
273                        new point(this.width-this.width/4,40),
274                        new point(this.width-this.width/4,this.height-40),
275                        new point(this.width,this.height-40),
276                        new point(this.width/2,this.height-1),
277                        new point(0,this.height-40),
278                        new point(this.width/4,this.height-40),
279                        new point(this.width/4,40),
280                        new point(0,40),
281                        new point(this.width/2,0),                      
282                     };
283                     break;
284             }
285             m_path = new graphicspath();
286             m_path.addlines(ps);
287             m_path.closeallfigures();
288         }
289 
290         /// <summary>
291         /// 引发 <see cref="e:system.windows.forms.control.paint" /> 事件。
292         /// </summary>
293         /// <param name="e">包含事件数据的 <see cref="t:system.windows.forms.painteventargs" />。</param>
294         protected override void onpaint(painteventargs e)
295         {
296             base.onpaint(e);
297             var g = e.graphics;
298             g.setgdihigh();
299 
300             g.fillpath(new solidbrush(arrowcolor), m_path);
301 
302             if (bordercolor != null && bordercolor != color.empty)
303                 g.drawpath(new pen(new solidbrush(bordercolor.value)), m_path);
304             if (!string.isnullorempty(text))
305             {
306                 var size = g.measurestring(text, font);
307                 g.drawstring(text, font, new solidbrush(forecolor), new pointf((this.width - size.width) / 2, (this.height - size.height) / 2));
308             }
309         }
310     }
311 
312     /// <summary>
313     /// enum arrowdirection
314     /// </summary>
315     public enum arrowdirection
316     {
317         /// <summary>
318         /// the left
319         /// </summary>
320         left,
321         /// <summary>
322         /// the right
323         /// </summary>
324         right,
325         /// <summary>
326         /// the top
327         /// </summary>
328         top,
329         /// <summary>
330         /// the bottom
331         /// </summary>
332         bottom,
333         /// <summary>
334         /// the left right
335         /// </summary>
336         left_right,
337         /// <summary>
338         /// the top bottom
339         /// </summary>
340         top_bottom
341     }
342 }

 

最后的话

如果你喜欢的话,请到  点个星星吧

《(六十三)c#Winform自定义控件-箭头(工业).doc》

下载本文的Word格式文档,以方便收藏与打印。