c#Winform自定义控件-温度计(工业)
程序员文章站
2023-12-24 18:08:51
前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:https://gitee.com/kwwwvagaa/net_winform_custom_contr ......
本文转自http://hzhcontrols.com/blogs.html
前提
一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
github:https://github.com/kwwwvagaa/netwinformcontrol
nuget
install-package hzh_controls
目录
用处及效果
准备工作
依然用gid+画的,不懂请自行百度
开始
添加一个类ucthermometer,继承usercontrol
添加一个枚举,来决定显示的温度单位
1 public enum temperatureunit 2 { 3 /// <summary> 4 /// 不显示 5 /// </summary> 6 none, 7 /// <summary> 8 /// 摄氏度 9 /// </summary> 10 c, 11 /// <summary> 12 /// 华氏度 13 /// </summary> 14 f, 15 /// <summary> 16 /// 开氏度 17 /// </summary> 18 k, 19 /// <summary> 20 /// 兰氏度 21 /// </summary> 22 r, 23 /// <summary> 24 /// 列氏度 25 /// </summary> 26 re 27 }
添加一些属性
1 /// <summary> 2 /// the glass tube color 3 /// </summary> 4 private color glasstubecolor = color.fromargb(211, 211, 211); 5 6 /// <summary> 7 /// gets or sets the color of the glass tube. 8 /// </summary> 9 /// <value>the color of the glass tube.</value> 10 [description("玻璃管颜色"), category("自定义")] 11 public color glasstubecolor 12 { 13 get { return glasstubecolor; } 14 set 15 { 16 glasstubecolor = value; 17 refresh(); 18 } 19 } 20 21 /// <summary> 22 /// the mercury color 23 /// </summary> 24 private color mercurycolor = color.fromargb(255, 77, 59); 25 26 /// <summary> 27 /// gets or sets the color of the mercury. 28 /// </summary> 29 /// <value>the color of the mercury.</value> 30 [description("水印颜色"), category("自定义")] 31 public color mercurycolor 32 { 33 get { return mercurycolor; } 34 set 35 { 36 mercurycolor = value; 37 refresh(); 38 } 39 } 40 41 /// <summary> 42 /// the minimum value 43 /// </summary> 44 private decimal minvalue = 0; 45 /// <summary> 46 /// 左侧刻度最小值 47 /// </summary> 48 /// <value>the minimum value.</value> 49 [description("左侧刻度最小值"), category("自定义")] 50 public decimal minvalue 51 { 52 get { return minvalue; } 53 set 54 { 55 minvalue = value; 56 refresh(); 57 } 58 } 59 60 /// <summary> 61 /// the maximum value 62 /// </summary> 63 private decimal maxvalue = 100; 64 /// <summary> 65 /// 左侧刻度最大值 66 /// </summary> 67 /// <value>the maximum value.</value> 68 [description("左侧刻度最大值"), category("自定义")] 69 public decimal maxvalue 70 { 71 get { return maxvalue; } 72 set 73 { 74 maxvalue = value; 75 refresh(); 76 } 77 } 78 79 /// <summary> 80 /// the m value 81 /// </summary> 82 private decimal m_value = 10; 83 /// <summary> 84 /// 左侧刻度值 85 /// </summary> 86 /// <value>the value.</value> 87 [description("左侧刻度值"), category("自定义")] 88 public decimal value 89 { 90 get { return m_value; } 91 set 92 { 93 m_value = value; 94 refresh(); 95 } 96 } 97 98 /// <summary> 99 /// the split count 100 /// </summary> 101 private int splitcount = 0; 102 /// <summary> 103 /// 刻度分隔份数 104 /// </summary> 105 /// <value>the split count.</value> 106 [description("刻度分隔份数"), category("自定义")] 107 public int splitcount 108 { 109 get { return splitcount; } 110 set 111 { 112 if (value <= 0) 113 return; 114 splitcount = value; 115 refresh(); 116 } 117 } 118 119 /// <summary> 120 /// 获取或设置控件显示的文字的字体。 121 /// </summary> 122 /// <value>the font.</value> 123 /// <permissionset> 124 /// <ipermission class="system.security.permissions.environmentpermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" /> 125 /// <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" /> 126 /// <ipermission class="system.security.permissions.securitypermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" flags="unmanagedcode, controlevidence" /> 127 /// <ipermission class="system.diagnostics.performancecounterpermission, system, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" /> 128 /// </permissionset> 129 [description("获取或设置控件显示的文字的字体"), category("自定义")] 130 public override font font 131 { 132 get 133 { 134 return base.font; 135 } 136 set 137 { 138 base.font = value; 139 refresh(); 140 } 141 } 142 143 /// <summary> 144 /// 获取或设置控件的前景色。 145 /// </summary> 146 /// <value>the color of the fore.</value> 147 /// <permissionset> 148 /// <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" /> 149 /// </permissionset> 150 [description("获取或设置控件的文字及刻度颜色"), category("自定义")] 151 public override system.drawing.color forecolor 152 { 153 get 154 { 155 return base.forecolor; 156 } 157 set 158 { 159 base.forecolor = value; 160 refresh(); 161 } 162 } 163 164 /// <summary> 165 /// the left temperature unit 166 /// </summary> 167 private temperatureunit lefttemperatureunit = temperatureunit.c; 168 /// <summary> 169 /// 左侧刻度单位,不可为none 170 /// </summary> 171 /// <value>the left temperature unit.</value> 172 [description("左侧刻度单位,不可为none"), category("自定义")] 173 public temperatureunit lefttemperatureunit 174 { 175 get { return lefttemperatureunit; } 176 set 177 { 178 if (value == temperatureunit.none) 179 return; 180 lefttemperatureunit = value; 181 refresh(); 182 } 183 } 184 185 /// <summary> 186 /// the right temperature unit 187 /// </summary> 188 private temperatureunit righttemperatureunit = temperatureunit.c; 189 /// <summary> 190 /// 右侧刻度单位,当为none时,不显示 191 /// </summary> 192 /// <value>the right temperature unit.</value> 193 [description("右侧刻度单位,当为none时,不显示"), category("自定义")] 194 public temperatureunit righttemperatureunit 195 { 196 get { return righttemperatureunit; } 197 set 198 { 199 righttemperatureunit = value; 200 refresh(); 201 } 202 } 203 204 /// <summary> 205 /// the m rect working 206 /// </summary> 207 rectangle m_rectworking; 208 /// <summary> 209 /// the m rect left 210 /// </summary> 211 rectangle m_rectleft; 212 /// <summary> 213 /// the m rect right 214 /// </summary> 215 rectangle m_rectright;
改变大小时,设定画图区域
1 void ucthermometer_sizechanged(object sender, eventargs e) 2 { 3 m_rectworking = new rectangle(this.width / 2 - this.width / 8, this.width / 4, this.width / 4, this.height - this.width / 2); 4 m_rectleft = new rectangle(0, m_rectworking.top + m_rectworking.width / 2, (this.width - this.width / 4) / 2 - 2, m_rectworking.height - m_rectworking.width * 2); 5 m_rectright = new rectangle(this.width - (this.width - this.width / 4) / 2 + 2, m_rectworking.top + m_rectworking.width / 2, (this.width - this.width / 4) / 2 - 2, m_rectworking.height - m_rectworking.width * 2); 6 }
重绘
1 protected override void onpaint(painteventargs e) 2 { 3 base.onpaint(e); 4 var g = e.graphics; 5 g.setgdihigh(); 6 7 //玻璃管管 8 graphicspath path = new graphicspath(); 9 path.addline(m_rectworking.left, m_rectworking.bottom, m_rectworking.left, m_rectworking.top + m_rectworking.width / 2); 10 path.addarc(new rectangle(m_rectworking.left, m_rectworking.top, m_rectworking.width, m_rectworking.width), 180, 180); 11 path.addline(m_rectworking.right, m_rectworking.top + m_rectworking.width / 2, m_rectworking.right, m_rectworking.bottom); 12 path.closeallfigures(); 13 g.fillpath(new solidbrush(glasstubecolor), path); 14 15 //底部 16 var rectdi = new rectangle(this.width / 2 - m_rectworking.width, m_rectworking.bottom - m_rectworking.width - 2, m_rectworking.width * 2, m_rectworking.width * 2); 17 g.fillellipse(new solidbrush(glasstubecolor), rectdi); 18 g.fillellipse(new solidbrush(mercurycolor), new rectangle(rectdi.left + 4, rectdi.top + 4, rectdi.width - 8, rectdi.height - 8)); 19 20 //刻度 21 decimal decsplit = (maxvalue - minvalue) / splitcount; 22 decimal decsplitheight = m_rectleft.height / splitcount; 23 for (int i = 0; i <= splitcount; i++) 24 { 25 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectleft.left + 2, (float)(m_rectleft.bottom - decsplitheight * i)), new pointf(m_rectleft.right, (float)(m_rectleft.bottom - decsplitheight * i))); 26 27 var valueleft = (minvalue + decsplit * i).tostring("0.##"); 28 var sizeleft = g.measurestring(valueleft, font); 29 g.drawstring(valueleft, font, new solidbrush(forecolor), new pointf(m_rectleft.left, m_rectleft.bottom - (float)decsplitheight * i - sizeleft.height - 1)); 30 31 if (righttemperatureunit != temperatureunit.none) 32 { 33 g.drawline(new pen(new solidbrush(color.black), 1), new pointf(m_rectright.left + 2, (float)(m_rectright.bottom - decsplitheight * i)), new pointf(m_rectright.right, (float)(m_rectright.bottom - decsplitheight * i))); 34 var valueright = getrightvalue(minvalue + decsplit * i).tostring("0.##"); 35 var sizeright = g.measurestring(valueright, font); 36 g.drawstring(valueright, font, new solidbrush(forecolor), new pointf(m_rectright.right - sizeright.width - 1, m_rectright.bottom - (float)decsplitheight * i - sizeright.height - 1)); 37 } 38 if (i != splitcount) 39 { 40 if (decsplitheight > 40) 41 { 42 var decsp1 = decsplitheight / 10; 43 for (int j = 1; j < 10; j++) 44 { 45 if (j == 5) 46 { 47 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectleft.right - 10, (m_rectleft.bottom - (float)decsplitheight * i - ((float)decsp1 * j))), new pointf(m_rectleft.right, (m_rectleft.bottom - (float)decsplitheight * i - ((float)decsp1 * j)))); 48 if (righttemperatureunit != temperatureunit.none) 49 { 50 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectright.left + 10, (m_rectright.bottom - (float)decsplitheight * i - ((float)decsp1 * j))), new pointf(m_rectright.left, (m_rectright.bottom - (float)decsplitheight * i - ((float)decsp1 * j)))); 51 } 52 } 53 else 54 { 55 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectleft.right - 5, (m_rectleft.bottom - (float)decsplitheight * i - ((float)decsp1 * j))), new pointf(m_rectleft.right, (m_rectleft.bottom - (float)decsplitheight * i - ((float)decsp1 * j)))); 56 if (righttemperatureunit != temperatureunit.none) 57 { 58 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectright.left + 5, (m_rectright.bottom - (float)decsplitheight * i - ((float)decsp1 * j))), new pointf(m_rectright.left, (m_rectright.bottom - (float)decsplitheight * i - ((float)decsp1 * j)))); 59 } 60 } 61 } 62 } 63 else if (decsplitheight > 10) 64 { 65 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectleft.right - 5, (m_rectleft.bottom - (float)decsplitheight * i - (float)decsplitheight / 2)), new pointf(m_rectleft.right, (m_rectleft.bottom - (float)decsplitheight * i - (float)decsplitheight / 2))); 66 if (righttemperatureunit != temperatureunit.none) 67 { 68 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectright.left + 5, (m_rectright.bottom - (float)decsplitheight * i - (float)decsplitheight / 2)), new pointf(m_rectright.left, (m_rectright.bottom - (float)decsplitheight * i - (float)decsplitheight / 2))); 69 } 70 } 71 } 72 } 73 //单位 74 string strleftunit = getunitchar(lefttemperatureunit); 75 g.drawstring(strleftunit, font, new solidbrush(forecolor), new pointf(m_rectleft.left + 2, 2)); 76 if (righttemperatureunit != temperatureunit.none) 77 { 78 string strrightunit = getunitchar(righttemperatureunit); 79 var rightsize = g.measurestring(strrightunit, font); 80 g.drawstring(strrightunit, font, new solidbrush(forecolor), new pointf(m_rectright.right - 2 - rightsize.width, 2)); 81 } 82 //值 83 float fltheightvalue = (float)(value / (maxvalue - minvalue) * m_rectleft.height); 84 rectanglef rectvalue = new rectanglef(m_rectworking.left + 4, m_rectleft.top + (m_rectleft.height - fltheightvalue), m_rectworking.width - 8, fltheightvalue + (m_rectworking.height - m_rectworking.width / 2 - m_rectleft.height)); 85 g.fillrectangle(new solidbrush(mercurycolor), rectvalue); 86 87 88 var sizevalue = g.measurestring(m_value.tostring("0.##"), font); 89 g.drawstring(m_value.tostring("0.##"), font, new solidbrush(color.white), new pointf(rectdi.left + (rectdi.width - sizevalue.width) / 2, rectdi.top + (rectdi.height - sizevalue.height) / 2 + 1)); 90 }
辅助函数
1 private string getunitchar(temperatureunit unit) 2 { 3 string strunit = "℃"; 4 switch (unit) 5 { 6 case temperatureunit.c: 7 strunit = "℃"; 8 break; 9 case temperatureunit.f: 10 strunit = "℉"; 11 break; 12 case temperatureunit.k: 13 strunit = "k"; 14 break; 15 case temperatureunit.r: 16 strunit = "°r"; 17 break; 18 case temperatureunit.re: 19 strunit = "°re"; 20 break; 21 } 22 return strunit; 23 } 24 25 private decimal getrightvalue(decimal decvalue) 26 { 27 //先将左侧的换算为摄氏度 28 var dec = decvalue; 29 switch (lefttemperatureunit) 30 { 31 case temperatureunit.f: 32 dec = (decvalue - 32) / (9m / 5m); 33 break; 34 case temperatureunit.k: 35 dec = decvalue - 273; 36 break; 37 case temperatureunit.r: 38 dec = decvalue / (5m / 9m) - 273.15m; 39 break; 40 case temperatureunit.re: 41 dec = decvalue / 1.25m; 42 break; 43 default: 44 break; 45 } 46 47 switch (righttemperatureunit) 48 { 49 case temperatureunit.c: 50 return dec; 51 case temperatureunit.f: 52 return 9m / 5m * dec + 32; 53 case temperatureunit.k: 54 return dec + 273; 55 case temperatureunit.r: 56 return (dec + 273.15m) * (5m / 9m); 57 case temperatureunit.re: 58 return dec * 1.25m; 59 } 60 return decvalue; 61 }
完整代码
1 // *********************************************************************** 2 // assembly : hzh_controls 3 // created : 2019-09-10 4 // 5 // *********************************************************************** 6 // <copyright file="ucthermometer.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 ucthermometer. 29 /// implements the <see cref="system.windows.forms.usercontrol" /> 30 /// </summary> 31 /// <seealso cref="system.windows.forms.usercontrol" /> 32 public class ucthermometer : usercontrol 33 { 34 /// <summary> 35 /// the glass tube color 36 /// </summary> 37 private color glasstubecolor = color.fromargb(211, 211, 211); 38 39 /// <summary> 40 /// gets or sets the color of the glass tube. 41 /// </summary> 42 /// <value>the color of the glass tube.</value> 43 [description("玻璃管颜色"), category("自定义")] 44 public color glasstubecolor 45 { 46 get { return glasstubecolor; } 47 set 48 { 49 glasstubecolor = value; 50 refresh(); 51 } 52 } 53 54 /// <summary> 55 /// the mercury color 56 /// </summary> 57 private color mercurycolor = color.fromargb(255, 77, 59); 58 59 /// <summary> 60 /// gets or sets the color of the mercury. 61 /// </summary> 62 /// <value>the color of the mercury.</value> 63 [description("水印颜色"), category("自定义")] 64 public color mercurycolor 65 { 66 get { return mercurycolor; } 67 set 68 { 69 mercurycolor = value; 70 refresh(); 71 } 72 } 73 74 /// <summary> 75 /// the minimum value 76 /// </summary> 77 private decimal minvalue = 0; 78 /// <summary> 79 /// 左侧刻度最小值 80 /// </summary> 81 /// <value>the minimum value.</value> 82 [description("左侧刻度最小值"), category("自定义")] 83 public decimal minvalue 84 { 85 get { return minvalue; } 86 set 87 { 88 minvalue = value; 89 refresh(); 90 } 91 } 92 93 /// <summary> 94 /// the maximum value 95 /// </summary> 96 private decimal maxvalue = 100; 97 /// <summary> 98 /// 左侧刻度最大值 99 /// </summary> 100 /// <value>the maximum value.</value> 101 [description("左侧刻度最大值"), category("自定义")] 102 public decimal maxvalue 103 { 104 get { return maxvalue; } 105 set 106 { 107 maxvalue = value; 108 refresh(); 109 } 110 } 111 112 /// <summary> 113 /// the m value 114 /// </summary> 115 private decimal m_value = 10; 116 /// <summary> 117 /// 左侧刻度值 118 /// </summary> 119 /// <value>the value.</value> 120 [description("左侧刻度值"), category("自定义")] 121 public decimal value 122 { 123 get { return m_value; } 124 set 125 { 126 m_value = value; 127 refresh(); 128 } 129 } 130 131 /// <summary> 132 /// the split count 133 /// </summary> 134 private int splitcount = 0; 135 /// <summary> 136 /// 刻度分隔份数 137 /// </summary> 138 /// <value>the split count.</value> 139 [description("刻度分隔份数"), category("自定义")] 140 public int splitcount 141 { 142 get { return splitcount; } 143 set 144 { 145 if (value <= 0) 146 return; 147 splitcount = value; 148 refresh(); 149 } 150 } 151 152 /// <summary> 153 /// 获取或设置控件显示的文字的字体。 154 /// </summary> 155 /// <value>the font.</value> 156 /// <permissionset> 157 /// <ipermission class="system.security.permissions.environmentpermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" /> 158 /// <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" /> 159 /// <ipermission class="system.security.permissions.securitypermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" flags="unmanagedcode, controlevidence" /> 160 /// <ipermission class="system.diagnostics.performancecounterpermission, system, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" /> 161 /// </permissionset> 162 [description("获取或设置控件显示的文字的字体"), category("自定义")] 163 public override font font 164 { 165 get 166 { 167 return base.font; 168 } 169 set 170 { 171 base.font = value; 172 refresh(); 173 } 174 } 175 176 /// <summary> 177 /// 获取或设置控件的前景色。 178 /// </summary> 179 /// <value>the color of the fore.</value> 180 /// <permissionset> 181 /// <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" /> 182 /// </permissionset> 183 [description("获取或设置控件的文字及刻度颜色"), category("自定义")] 184 public override system.drawing.color forecolor 185 { 186 get 187 { 188 return base.forecolor; 189 } 190 set 191 { 192 base.forecolor = value; 193 refresh(); 194 } 195 } 196 197 /// <summary> 198 /// the left temperature unit 199 /// </summary> 200 private temperatureunit lefttemperatureunit = temperatureunit.c; 201 /// <summary> 202 /// 左侧刻度单位,不可为none 203 /// </summary> 204 /// <value>the left temperature unit.</value> 205 [description("左侧刻度单位,不可为none"), category("自定义")] 206 public temperatureunit lefttemperatureunit 207 { 208 get { return lefttemperatureunit; } 209 set 210 { 211 if (value == temperatureunit.none) 212 return; 213 lefttemperatureunit = value; 214 refresh(); 215 } 216 } 217 218 /// <summary> 219 /// the right temperature unit 220 /// </summary> 221 private temperatureunit righttemperatureunit = temperatureunit.c; 222 /// <summary> 223 /// 右侧刻度单位,当为none时,不显示 224 /// </summary> 225 /// <value>the right temperature unit.</value> 226 [description("右侧刻度单位,当为none时,不显示"), category("自定义")] 227 public temperatureunit righttemperatureunit 228 { 229 get { return righttemperatureunit; } 230 set 231 { 232 righttemperatureunit = value; 233 refresh(); 234 } 235 } 236 237 /// <summary> 238 /// the m rect working 239 /// </summary> 240 rectangle m_rectworking; 241 /// <summary> 242 /// the m rect left 243 /// </summary> 244 rectangle m_rectleft; 245 /// <summary> 246 /// the m rect right 247 /// </summary> 248 rectangle m_rectright; 249 /// <summary> 250 /// initializes a new instance of the <see cref="ucthermometer"/> class. 251 /// </summary> 252 public ucthermometer() 253 { 254 this.setstyle(controlstyles.allpaintinginwmpaint, true); 255 this.setstyle(controlstyles.doublebuffer, true); 256 this.setstyle(controlstyles.resizeredraw, true); 257 this.setstyle(controlstyles.selectable, true); 258 this.setstyle(controlstyles.supportstransparentbackcolor, true); 259 this.setstyle(controlstyles.userpaint, true); 260 this.autoscalemode = system.windows.forms.autoscalemode.none; 261 this.sizechanged += ucthermometer_sizechanged; 262 this.size = new size(70, 200); 263 } 264 265 /// <summary> 266 /// handles the sizechanged event of the ucthermometer control. 267 /// </summary> 268 /// <param name="sender">the source of the event.</param> 269 /// <param name="e">the <see cref="eventargs"/> instance containing the event data.</param> 270 void ucthermometer_sizechanged(object sender, eventargs e) 271 { 272 m_rectworking = new rectangle(this.width / 2 - this.width / 8, this.width / 4, this.width / 4, this.height - this.width / 2); 273 m_rectleft = new rectangle(0, m_rectworking.top + m_rectworking.width / 2, (this.width - this.width / 4) / 2 - 2, m_rectworking.height - m_rectworking.width * 2); 274 m_rectright = new rectangle(this.width - (this.width - this.width / 4) / 2 + 2, m_rectworking.top + m_rectworking.width / 2, (this.width - this.width / 4) / 2 - 2, m_rectworking.height - m_rectworking.width * 2); 275 } 276 277 /// <summary> 278 /// 引发 <see cref="e:system.windows.forms.control.paint" /> 事件。 279 /// </summary> 280 /// <param name="e">包含事件数据的 <see cref="t:system.windows.forms.painteventargs" />。</param> 281 protected override void onpaint(painteventargs e) 282 { 283 base.onpaint(e); 284 var g = e.graphics; 285 g.setgdihigh(); 286 287 //玻璃管管 288 graphicspath path = new graphicspath(); 289 path.addline(m_rectworking.left, m_rectworking.bottom, m_rectworking.left, m_rectworking.top + m_rectworking.width / 2); 290 path.addarc(new rectangle(m_rectworking.left, m_rectworking.top, m_rectworking.width, m_rectworking.width), 180, 180); 291 path.addline(m_rectworking.right, m_rectworking.top + m_rectworking.width / 2, m_rectworking.right, m_rectworking.bottom); 292 path.closeallfigures(); 293 g.fillpath(new solidbrush(glasstubecolor), path); 294 295 //底部 296 var rectdi = new rectangle(this.width / 2 - m_rectworking.width, m_rectworking.bottom - m_rectworking.width - 2, m_rectworking.width * 2, m_rectworking.width * 2); 297 g.fillellipse(new solidbrush(glasstubecolor), rectdi); 298 g.fillellipse(new solidbrush(mercurycolor), new rectangle(rectdi.left + 4, rectdi.top + 4, rectdi.width - 8, rectdi.height - 8)); 299 300 //刻度 301 decimal decsplit = (maxvalue - minvalue) / splitcount; 302 decimal decsplitheight = m_rectleft.height / splitcount; 303 for (int i = 0; i <= splitcount; i++) 304 { 305 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectleft.left + 2, (float)(m_rectleft.bottom - decsplitheight * i)), new pointf(m_rectleft.right, (float)(m_rectleft.bottom - decsplitheight * i))); 306 307 var valueleft = (minvalue + decsplit * i).tostring("0.##"); 308 var sizeleft = g.measurestring(valueleft, font); 309 g.drawstring(valueleft, font, new solidbrush(forecolor), new pointf(m_rectleft.left, m_rectleft.bottom - (float)decsplitheight * i - sizeleft.height - 1)); 310 311 if (righttemperatureunit != temperatureunit.none) 312 { 313 g.drawline(new pen(new solidbrush(color.black), 1), new pointf(m_rectright.left + 2, (float)(m_rectright.bottom - decsplitheight * i)), new pointf(m_rectright.right, (float)(m_rectright.bottom - decsplitheight * i))); 314 var valueright = getrightvalue(minvalue + decsplit * i).tostring("0.##"); 315 var sizeright = g.measurestring(valueright, font); 316 g.drawstring(valueright, font, new solidbrush(forecolor), new pointf(m_rectright.right - sizeright.width - 1, m_rectright.bottom - (float)decsplitheight * i - sizeright.height - 1)); 317 } 318 if (i != splitcount) 319 { 320 if (decsplitheight > 40) 321 { 322 var decsp1 = decsplitheight / 10; 323 for (int j = 1; j < 10; j++) 324 { 325 if (j == 5) 326 { 327 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectleft.right - 10, (m_rectleft.bottom - (float)decsplitheight * i - ((float)decsp1 * j))), new pointf(m_rectleft.right, (m_rectleft.bottom - (float)decsplitheight * i - ((float)decsp1 * j)))); 328 if (righttemperatureunit != temperatureunit.none) 329 { 330 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectright.left + 10, (m_rectright.bottom - (float)decsplitheight * i - ((float)decsp1 * j))), new pointf(m_rectright.left, (m_rectright.bottom - (float)decsplitheight * i - ((float)decsp1 * j)))); 331 } 332 } 333 else 334 { 335 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectleft.right - 5, (m_rectleft.bottom - (float)decsplitheight * i - ((float)decsp1 * j))), new pointf(m_rectleft.right, (m_rectleft.bottom - (float)decsplitheight * i - ((float)decsp1 * j)))); 336 if (righttemperatureunit != temperatureunit.none) 337 { 338 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectright.left + 5, (m_rectright.bottom - (float)decsplitheight * i - ((float)decsp1 * j))), new pointf(m_rectright.left, (m_rectright.bottom - (float)decsplitheight * i - ((float)decsp1 * j)))); 339 } 340 } 341 } 342 } 343 else if (decsplitheight > 10) 344 { 345 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectleft.right - 5, (m_rectleft.bottom - (float)decsplitheight * i - (float)decsplitheight / 2)), new pointf(m_rectleft.right, (m_rectleft.bottom - (float)decsplitheight * i - (float)decsplitheight / 2))); 346 if (righttemperatureunit != temperatureunit.none) 347 { 348 g.drawline(new pen(new solidbrush(forecolor), 1), new pointf(m_rectright.left + 5, (m_rectright.bottom - (float)decsplitheight * i - (float)decsplitheight / 2)), new pointf(m_rectright.left, (m_rectright.bottom - (float)decsplitheight * i - (float)decsplitheight / 2))); 349 } 350 } 351 } 352 } 353 //单位 354 string strleftunit = getunitchar(lefttemperatureunit); 355 g.drawstring(strleftunit, font, new solidbrush(forecolor), new pointf(m_rectleft.left + 2, 2)); 356 if (righttemperatureunit != temperatureunit.none) 357 { 358 string strrightunit = getunitchar(righttemperatureunit); 359 var rightsize = g.measurestring(strrightunit, font); 360 g.drawstring(strrightunit, font, new solidbrush(forecolor), new pointf(m_rectright.right - 2 - rightsize.width, 2)); 361 } 362 //值 363 float fltheightvalue = (float)(value / (maxvalue - minvalue) * m_rectleft.height); 364 rectanglef rectvalue = new rectanglef(m_rectworking.left + 4, m_rectleft.top + (m_rectleft.height - fltheightvalue), m_rectworking.width - 8, fltheightvalue + (m_rectworking.height - m_rectworking.width / 2 - m_rectleft.height)); 365 g.fillrectangle(new solidbrush(mercurycolor), rectvalue); 366 367 368 var sizevalue = g.measurestring(m_value.tostring("0.##"), font); 369 g.drawstring(m_value.tostring("0.##"), font, new solidbrush(color.white), new pointf(rectdi.left + (rectdi.width - sizevalue.width) / 2, rectdi.top + (rectdi.height - sizevalue.height) / 2 + 1)); 370 } 371 372 private string getunitchar(temperatureunit unit) 373 { 374 string strunit = "℃"; 375 switch (unit) 376 { 377 case temperatureunit.c: 378 strunit = "℃"; 379 break; 380 case temperatureunit.f: 381 strunit = "℉"; 382 break; 383 case temperatureunit.k: 384 strunit = "k"; 385 break; 386 case temperatureunit.r: 387 strunit = "°r"; 388 break; 389 case temperatureunit.re: 390 strunit = "°re"; 391 break; 392 } 393 return strunit; 394 } 395 396 private decimal getrightvalue(decimal decvalue) 397 { 398 //先将左侧的换算为摄氏度 399 var dec = decvalue; 400 switch (lefttemperatureunit) 401 { 402 case temperatureunit.f: 403 dec = (decvalue - 32) / (9m / 5m); 404 break; 405 case temperatureunit.k: 406 dec = decvalue - 273; 407 break; 408 case temperatureunit.r: 409 dec = decvalue / (5m / 9m) - 273.15m; 410 break; 411 case temperatureunit.re: 412 dec = decvalue / 1.25m; 413 break; 414 default: 415 break; 416 } 417 418 switch (righttemperatureunit) 419 { 420 case temperatureunit.c: 421 return dec; 422 case temperatureunit.f: 423 return 9m / 5m * dec + 32; 424 case temperatureunit.k: 425 return dec + 273; 426 case temperatureunit.r: 427 return (dec + 273.15m) * (5m / 9m); 428 case temperatureunit.re: 429 return dec * 1.25m; 430 } 431 return decvalue; 432 } 433 } 434 435 /// <summary> 436 /// enum temperatureunit 437 /// </summary> 438 public enum temperatureunit 439 { 440 /// <summary> 441 /// 不显示 442 /// </summary> 443 none, 444 /// <summary> 445 /// 摄氏度 446 /// </summary> 447 c, 448 /// <summary> 449 /// 华氏度 450 /// </summary> 451 f, 452 /// <summary> 453 /// 开氏度 454 /// </summary> 455 k, 456 /// <summary> 457 /// 兰氏度 458 /// </summary> 459 r, 460 /// <summary> 461 /// 列氏度 462 /// </summary> 463 re 464 } 465 }
最后的话
如果你喜欢的话,请到 点个星星吧