(五十七)c#Winform自定义控件-传送带(工业)
程序员文章站
2022-07-02 13:00:14
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:https://gitee.com/kwwwvagaa/net_winform_custom_contr ......
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
github:https://github.com/kwwwvagaa/netwinformcontrol
码云:
如果觉得写的还行,请点个 star 支持一下吧
欢迎前来交流探讨: 企鹅群568015492
麻烦博客下方点个【推荐】,谢谢
nuget
install-package hzh_controls
目录
用处及效果
准备工作
依然gdi+和三角函数,不懂可以先百度下
一个控制转动方向的枚举
1 public enum conveyordirection 2 { 3 /// <summary> 4 /// the none 5 /// </summary> 6 none, 7 /// <summary> 8 /// the forward 9 /// </summary> 10 forward, 11 /// <summary> 12 /// the backward 13 /// </summary> 14 backward 15 }
一些控制属性
1 /// <summary> 2 /// the conveyor color 3 /// </summary> 4 private color conveyorcolor = color.fromargb(255, 77, 59); 5 6 /// <summary> 7 /// gets or sets the color of the conveyor. 8 /// </summary> 9 /// <value>the color of the conveyor.</value> 10 [description("传送带颜色"), category("自定义")] 11 public color conveyorcolor 12 { 13 get { return conveyorcolor; } 14 set 15 { 16 conveyorcolor = value; 17 refresh(); 18 } 19 } 20 21 /// <summary> 22 /// the inclination 23 /// </summary> 24 private double inclination = 0; 25 26 /// <summary> 27 /// gets or sets the inclination. 28 /// </summary> 29 /// <value>the inclination.</value> 30 [description("传送带角度(-90<=value<=90)"), category("自定义")] 31 public double inclination 32 { 33 get { return inclination; } 34 set 35 { 36 if (value > 90 || value < -90) 37 return; 38 inclination = value; 39 resetworkingrect(); 40 refresh(); 41 } 42 } 43 44 /// <summary> 45 /// the conveyor height 46 /// </summary> 47 private int conveyorheight = 50; 48 49 /// <summary> 50 /// gets or sets the height of the conveyor. 51 /// </summary> 52 /// <value>the height of the conveyor.</value> 53 [description("传送带高度"), category("自定义")] 54 public int conveyorheight 55 { 56 get { return conveyorheight; } 57 set 58 { 59 conveyorheight = value; 60 resetworkingrect(); 61 refresh(); 62 } 63 } 64 65 /// <summary> 66 /// the conveyor direction 67 /// </summary> 68 private conveyordirection conveyordirection = conveyordirection.forward; 69 70 /// <summary> 71 /// gets or sets the conveyor direction. 72 /// </summary> 73 /// <value>the conveyor direction.</value> 74 [description("传送带运行方向"), category("自定义")] 75 public conveyordirection conveyordirection 76 { 77 get { return conveyordirection; } 78 set 79 { 80 conveyordirection = value; 81 if (value == hzh_controls.controls.conveyordirection.none) 82 { 83 m_timer.enabled = false; 84 refresh(); 85 } 86 else 87 { 88 m_timer.enabled = true; 89 } 90 } 91 } 92 93 /// <summary> 94 /// the liquid speed 95 /// </summary> 96 private int conveyorspeed = 100; 97 98 /// <summary> 99 /// 传送带运行速度,越小,速度越快gets or sets the conveyorspeed. 100 /// </summary> 101 /// <value>the liquid speed.</value> 102 [description("传送带运行速度,越小,速度越快"), category("自定义")] 103 public int conveyorspeed 104 { 105 get { return conveyorspeed; } 106 set 107 { 108 if (value <= 0) 109 return; 110 conveyorspeed = value; 111 m_timer.interval = value; 112 } 113 } 114 115 /// <summary> 116 /// the m working rect 117 /// </summary> 118 rectangle m_workingrect; 119 /// <summary> 120 /// the int line left 121 /// </summary> 122 int intlineleft = 0; 123 /// <summary> 124 /// the m timer 125 /// </summary> 126 timer m_timer;
大小和角度改变时重算画图区域
1 void ucconveyor_sizechanged(object sender, eventargs e) 2 { 3 resetworkingrect(); 4 } 5 6 /// <summary> 7 /// resets the working rect. 8 /// </summary> 9 private void resetworkingrect() 10 { 11 if (inclination == 90 || inclination == -90) 12 { 13 m_workingrect = new rectangle((this.width - conveyorheight) / 2, 1, conveyorheight, this.height - 2); 14 } 15 else if (inclination == 0) 16 { 17 m_workingrect = new rectangle(1, (this.height - conveyorheight) / 2 + 1, this.width - 2, conveyorheight); 18 } 19 else 20 { 21 //根据角度计算需要的高度 22 int intheight = (int)(math.tan(math.pi * (math.abs(inclination) / 180.00000)) * (this.width)); 23 if (intheight >= this.height) 24 intheight = this.height; 25 26 int intwidth = (int)(intheight / (math.tan(math.pi * (math.abs(inclination) / 180.00000)))); 27 intheight += conveyorheight; 28 if (intheight >= this.height) 29 intheight = this.height; 30 m_workingrect = new rectangle((this.width - intwidth) / 2 + 1, (this.height - intheight) / 2 + 1, intwidth - 2, intheight - 2); 31 } 32 33 }
最重要的重绘
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 var g = e.graphics; 9 g.setgdihigh(); 10 //g.fillrectangle(new solidbrush(color.fromargb(100, conveyorcolor)), m_workingrect); 11 12 //轴 13 //左端 14 var rectleft = new rectangle(m_workingrect.left + 5, (inclination >= 0 ? (m_workingrect.bottom - conveyorheight) : m_workingrect.top) + 5, conveyorheight - 10, conveyorheight - 10); 15 g.fillellipse(new solidbrush(conveyorcolor), rectleft); 16 g.fillellipse(new solidbrush(color.white), new rectangle(rectleft.left + (rectleft.width - 6) / 2, rectleft.top + (rectleft.height - 6) / 2, 6, 6)); 17 //右端 18 var rectright = new rectangle(m_workingrect.right - conveyorheight + 5, (inclination >= 0 ? (m_workingrect.top) : (m_workingrect.bottom - conveyorheight)) + 5, conveyorheight - 10, conveyorheight - 10); 19 g.fillellipse(new solidbrush(conveyorcolor), rectright); 20 g.fillellipse(new solidbrush(color.white), new rectangle(rectright.left + (rectright.width - 6) / 2, rectright.top + (rectright.height - 6) / 2, 6, 6)); 21 22 23 //传送带 24 //左端 25 graphicspath path = new graphicspath(); 26 path.addarc(new rectangle(m_workingrect.left, (inclination >= 0 ? (m_workingrect.bottom - conveyorheight) : m_workingrect.top), conveyorheight, conveyorheight), 90f - (float)inclination, 180f); 27 //右端 28 path.addarc(new rectangle(m_workingrect.right - conveyorheight, (inclination >= 0 ? (m_workingrect.top) : (m_workingrect.bottom - conveyorheight)), conveyorheight, conveyorheight), 270 - (float)inclination, 180f); 29 path.closeallfigures(); 30 g.drawpath(new pen(new solidbrush(conveyorcolor), 3), path); 31 32 //液体流动 33 if (conveyordirection != conveyordirection.none) 34 { 35 pen p = new pen(new solidbrush(color.fromargb(150, this.backcolor)), 4); 36 p.dashpattern = new float[] { 6, 6 }; 37 p.dashoffset = intlineleft * (conveyordirection == conveyordirection.forward ? -1 : 1); 38 g.drawpath(p, path); 39 } 40 } 41 }
完整代码
1 // *********************************************************************** 2 // assembly : hzh_controls 3 // created : 2019-09-05 4 // 5 // *********************************************************************** 6 // <copyright file="ucconveyor.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 ucconveyor. 29 /// implements the <see cref="system.windows.forms.usercontrol" /> 30 /// </summary> 31 /// <seealso cref="system.windows.forms.usercontrol" /> 32 public class ucconveyor : usercontrol 33 { 34 /// <summary> 35 /// the conveyor color 36 /// </summary> 37 private color conveyorcolor = color.fromargb(255, 77, 59); 38 39 /// <summary> 40 /// gets or sets the color of the conveyor. 41 /// </summary> 42 /// <value>the color of the conveyor.</value> 43 [description("传送带颜色"), category("自定义")] 44 public color conveyorcolor 45 { 46 get { return conveyorcolor; } 47 set 48 { 49 conveyorcolor = value; 50 refresh(); 51 } 52 } 53 54 /// <summary> 55 /// the inclination 56 /// </summary> 57 private double inclination = 0; 58 59 /// <summary> 60 /// gets or sets the inclination. 61 /// </summary> 62 /// <value>the inclination.</value> 63 [description("传送带角度(-90<=value<=90)"), category("自定义")] 64 public double inclination 65 { 66 get { return inclination; } 67 set 68 { 69 if (value > 90 || value < -90) 70 return; 71 inclination = value; 72 resetworkingrect(); 73 refresh(); 74 } 75 } 76 77 /// <summary> 78 /// the conveyor height 79 /// </summary> 80 private int conveyorheight = 50; 81 82 /// <summary> 83 /// gets or sets the height of the conveyor. 84 /// </summary> 85 /// <value>the height of the conveyor.</value> 86 [description("传送带高度"), category("自定义")] 87 public int conveyorheight 88 { 89 get { return conveyorheight; } 90 set 91 { 92 conveyorheight = value; 93 resetworkingrect(); 94 refresh(); 95 } 96 } 97 98 /// <summary> 99 /// the conveyor direction 100 /// </summary> 101 private conveyordirection conveyordirection = conveyordirection.forward; 102 103 /// <summary> 104 /// gets or sets the conveyor direction. 105 /// </summary> 106 /// <value>the conveyor direction.</value> 107 [description("传送带运行方向"), category("自定义")] 108 public conveyordirection conveyordirection 109 { 110 get { return conveyordirection; } 111 set 112 { 113 conveyordirection = value; 114 if (value == hzh_controls.controls.conveyordirection.none) 115 { 116 m_timer.enabled = false; 117 refresh(); 118 } 119 else 120 { 121 m_timer.enabled = true; 122 } 123 } 124 } 125 126 /// <summary> 127 /// the liquid speed 128 /// </summary> 129 private int conveyorspeed = 100; 130 131 /// <summary> 132 /// 传送带运行速度,越小,速度越快gets or sets the conveyorspeed. 133 /// </summary> 134 /// <value>the liquid speed.</value> 135 [description("传送带运行速度,越小,速度越快"), category("自定义")] 136 public int conveyorspeed 137 { 138 get { return conveyorspeed; } 139 set 140 { 141 if (value <= 0) 142 return; 143 conveyorspeed = value; 144 m_timer.interval = value; 145 } 146 } 147 148 /// <summary> 149 /// the m working rect 150 /// </summary> 151 rectangle m_workingrect; 152 /// <summary> 153 /// the int line left 154 /// </summary> 155 int intlineleft = 0; 156 /// <summary> 157 /// the m timer 158 /// </summary> 159 timer m_timer; 160 /// <summary> 161 /// initializes a new instance of the <see cref="ucconveyor"/> class. 162 /// </summary> 163 public ucconveyor() 164 { 165 this.setstyle(controlstyles.allpaintinginwmpaint, true); 166 this.setstyle(controlstyles.doublebuffer, true); 167 this.setstyle(controlstyles.resizeredraw, true); 168 this.setstyle(controlstyles.selectable, true); 169 this.setstyle(controlstyles.supportstransparentbackcolor, true); 170 this.setstyle(controlstyles.userpaint, true); 171 this.sizechanged += ucconveyor_sizechanged; 172 this.size = new size(300, 50); 173 m_timer = new timer(); 174 m_timer.interval = 100; 175 m_timer.tick += timer_tick; 176 m_timer.enabled = true; 177 } 178 179 /// <summary> 180 /// handles the tick event of the timer control. 181 /// </summary> 182 /// <param name="sender">the source of the event.</param> 183 /// <param name="e">the <see cref="eventargs"/> instance containing the event data.</param> 184 void timer_tick(object sender, eventargs e) 185 { 186 intlineleft += 2; 187 if (intlineleft > 12) 188 intlineleft = 0; 189 refresh(); 190 } 191 192 /// <summary> 193 /// handles the sizechanged event of the ucconveyor control. 194 /// </summary> 195 /// <param name="sender">the source of the event.</param> 196 /// <param name="e">the <see cref="eventargs"/> instance containing the event data.</param> 197 void ucconveyor_sizechanged(object sender, eventargs e) 198 { 199 resetworkingrect(); 200 } 201 202 /// <summary> 203 /// resets the working rect. 204 /// </summary> 205 private void resetworkingrect() 206 { 207 if (inclination == 90 || inclination == -90) 208 { 209 m_workingrect = new rectangle((this.width - conveyorheight) / 2, 1, conveyorheight, this.height - 2); 210 } 211 else if (inclination == 0) 212 { 213 m_workingrect = new rectangle(1, (this.height - conveyorheight) / 2 + 1, this.width - 2, conveyorheight); 214 } 215 else 216 { 217 //根据角度计算需要的高度 218 int intheight = (int)(math.tan(math.pi * (math.abs(inclination) / 180.00000)) * (this.width)); 219 if (intheight >= this.height) 220 intheight = this.height; 221 222 int intwidth = (int)(intheight / (math.tan(math.pi * (math.abs(inclination) / 180.00000)))); 223 intheight += conveyorheight; 224 if (intheight >= this.height) 225 intheight = this.height; 226 m_workingrect = new rectangle((this.width - intwidth) / 2 + 1, (this.height - intheight) / 2 + 1, intwidth - 2, intheight - 2); 227 } 228 229 } 230 231 /// <summary> 232 /// 引发 <see cref="e:system.windows.forms.control.paint" /> 事件。 233 /// </summary> 234 /// <param name="e">包含事件数据的 <see cref="t:system.windows.forms.painteventargs" />。</param> 235 protected override void onpaint(painteventargs e) 236 { 237 base.onpaint(e); 238 var g = e.graphics; 239 g.setgdihigh(); 240 //g.fillrectangle(new solidbrush(color.fromargb(100, conveyorcolor)), m_workingrect); 241 242 //轴 243 //左端 244 var rectleft = new rectangle(m_workingrect.left + 5, (inclination >= 0 ? (m_workingrect.bottom - conveyorheight) : m_workingrect.top) + 5, conveyorheight - 10, conveyorheight - 10); 245 g.fillellipse(new solidbrush(conveyorcolor), rectleft); 246 g.fillellipse(new solidbrush(color.white), new rectangle(rectleft.left + (rectleft.width - 6) / 2, rectleft.top + (rectleft.height - 6) / 2, 6, 6)); 247 //右端 248 var rectright = new rectangle(m_workingrect.right - conveyorheight + 5, (inclination >= 0 ? (m_workingrect.top) : (m_workingrect.bottom - conveyorheight)) + 5, conveyorheight - 10, conveyorheight - 10); 249 g.fillellipse(new solidbrush(conveyorcolor), rectright); 250 g.fillellipse(new solidbrush(color.white), new rectangle(rectright.left + (rectright.width - 6) / 2, rectright.top + (rectright.height - 6) / 2, 6, 6)); 251 252 253 //传送带 254 //左端 255 graphicspath path = new graphicspath(); 256 path.addarc(new rectangle(m_workingrect.left, (inclination >= 0 ? (m_workingrect.bottom - conveyorheight) : m_workingrect.top), conveyorheight, conveyorheight), 90f - (float)inclination, 180f); 257 //右端 258 path.addarc(new rectangle(m_workingrect.right - conveyorheight, (inclination >= 0 ? (m_workingrect.top) : (m_workingrect.bottom - conveyorheight)), conveyorheight, conveyorheight), 270 - (float)inclination, 180f); 259 path.closeallfigures(); 260 g.drawpath(new pen(new solidbrush(conveyorcolor), 3), path); 261 262 //液体流动 263 if (conveyordirection != conveyordirection.none) 264 { 265 pen p = new pen(new solidbrush(color.fromargb(150, this.backcolor)), 4); 266 p.dashpattern = new float[] { 6, 6 }; 267 p.dashoffset = intlineleft * (conveyordirection == conveyordirection.forward ? -1 : 1); 268 g.drawpath(p, path); 269 } 270 } 271 } 272 273 /// <summary> 274 /// enum conveyordirection 275 /// </summary> 276 public enum conveyordirection 277 { 278 /// <summary> 279 /// the none 280 /// </summary> 281 none, 282 /// <summary> 283 /// the forward 284 /// </summary> 285 forward, 286 /// <summary> 287 /// the backward 288 /// </summary> 289 backward 290 } 291 }
开始
最后的话
如果你喜欢的话,请到 点个星星吧