本文共 32581 字,大约阅读时间需要 108 分钟。
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:
码云:
如果觉得写的还行,请点个 star 支持一下吧
欢迎前来交流探讨: 企鹅群568015492
麻烦博客下方点个【推荐】,谢谢
Install-Package HZH_Controls
依然使用GDI+画的,不懂的话就百度一下吧
另外主要用到了三角函数,如果不懂,可以向初中的数学老师再问问(你也可以百度一下)
添加一个类UCMeter 继承 UserControl
首先添加一个需要控制的属性
1 private int splitCount = 10; 2 ///3 /// Gets or sets the split count. 4 /// 5 ///The split count. 6 [Description("分隔刻度数量,>1"), Category("自定义")] 7 public int SplitCount 8 { 9 get { return splitCount; } 10 set 11 { 12 if (value < 1) 13 return; 14 splitCount = value; 15 Refresh(); 16 } 17 } 18 19 private int meterDegrees = 150; 20 ///21 /// Gets or sets the meter degrees. 22 /// 23 ///The meter degrees. 24 [Description("表盘跨度角度,0-360"), Category("自定义")] 25 public int MeterDegrees 26 { 27 get { return meterDegrees; } 28 set 29 { 30 if (value > 360 || value <= 0) 31 return; 32 meterDegrees = value; 33 Refresh(); 34 } 35 } 36 37 private decimal minValue = 0; 38 ///39 /// Gets or sets the minimum value. 40 /// 41 ///The minimum value. 42 [Description("最小值,= maxValue) 49 return; 50 minValue = value; 51 Refresh(); 52 } 53 } 54 55 private decimal maxValue = 100; 56 /// 57 /// Gets or sets the maximum value. 58 /// 59 ///The maximum value. 60 [Description("最大值,>MinValue"), Category("自定义")] 61 public decimal MaxValue 62 { 63 get { return maxValue; } 64 set 65 { 66 if (value <= minValue) 67 return; 68 maxValue = value; 69 Refresh(); 70 } 71 } 72 ///73 /// 获取或设置控件显示的文字的字体。 74 /// 75 ///The font. 76 ///77 /// 82 [Description("刻度字体"), Category("自定义")] 83 public override Font Font 84 { 85 get 86 { 87 return base.Font; 88 } 89 set 90 { 91 base.Font = value; 92 Refresh(); 93 } 94 } 95 96 private decimal m_value = 0; 97 ///78 /// 79 /// 80 /// 81 /// 98 /// Gets or sets the value. 99 /// 100 ///The value. 101 [Description("值,>=MinValue并且<=MaxValue"), Category("自定义")]102 public decimal Value103 {104 get { return m_value; }105 set106 {107 if (value < minValue || value > maxValue)108 return;109 m_value = value;110 Refresh();111 }112 }113 114 private MeterTextLocation textLocation = MeterTextLocation.None;115 ///116 /// Gets or sets the text location.117 /// 118 ///The text location. 119 [Description("值和固定文字显示位置"), Category("自定义")]120 public MeterTextLocation TextLocation121 {122 get { return textLocation; }123 set124 {125 textLocation = value;126 Refresh();127 }128 }129 130 private string fixedText;131 ///132 /// Gets or sets the fixed text.133 /// 134 ///The fixed text. 135 [Description("固定文字"), Category("自定义")]136 public string FixedText137 {138 get { return fixedText; }139 set140 {141 fixedText = value;142 Refresh();143 }144 }145 146 private Font textFont = DefaultFont;147 ///148 /// Gets or sets the text font.149 /// 150 ///The text font. 151 [Description("值和固定文字字体"), Category("自定义")]152 public Font TextFont153 {154 get { return textFont; }155 set156 {157 textFont = value;158 Refresh();159 }160 }161 162 private Color externalRoundColor = Color.FromArgb(255, 77, 59);163 ///164 /// Gets or sets the color of the external round.165 /// 166 ///The color of the external round. 167 [Description("外圆颜色"), Category("自定义")]168 public Color ExternalRoundColor169 {170 get { return externalRoundColor; }171 set172 {173 externalRoundColor = value;174 Refresh();175 }176 }177 178 private Color insideRoundColor = Color.FromArgb(255, 77, 59);179 ///180 /// Gets or sets the color of the inside round.181 /// 182 ///The color of the inside round. 183 [Description("内圆颜色"), Category("自定义")]184 public Color InsideRoundColor185 {186 get { return insideRoundColor; }187 set188 {189 insideRoundColor = value;190 Refresh();191 }192 }193 194 private Color boundaryLineColor = Color.FromArgb(255, 77, 59);195 ///196 /// Gets or sets the color of the boundary line.197 /// 198 ///The color of the boundary line. 199 [Description("边界线颜色"), Category("自定义")]200 public Color BoundaryLineColor201 {202 get { return boundaryLineColor; }203 set204 {205 boundaryLineColor = value;206 Refresh();207 }208 }209 210 private Color scaleColor = Color.FromArgb(255, 77, 59);211 ///212 /// Gets or sets the color of the scale.213 /// 214 ///The color of the scale. 215 [Description("刻度颜色"), Category("自定义")]216 public Color ScaleColor217 {218 get { return scaleColor; }219 set220 {221 scaleColor = value;222 Refresh();223 }224 }225 226 private Color scaleValueColor = Color.FromArgb(255, 77, 59);227 ///228 /// Gets or sets the color of the scale value.229 /// 230 ///The color of the scale value. 231 [Description("刻度值文字颜色"), Category("自定义")]232 public Color ScaleValueColor233 {234 get { return scaleValueColor; }235 set236 {237 scaleValueColor = value;238 Refresh();239 }240 }241 242 private Color pointerColor = Color.FromArgb(255, 77, 59);243 ///244 /// Gets or sets the color of the pointer.245 /// 246 ///The color of the pointer. 247 [Description("指针颜色"), Category("自定义")]248 public Color PointerColor249 {250 get { return pointerColor; }251 set252 {253 pointerColor = value;254 Refresh();255 }256 }257 258 private Color textColor = Color.FromArgb(255, 77, 59);259 ///260 /// Gets or sets the color of the text.261 /// 262 ///The color of the text. 263 [Description("值和固定文字颜色"), Category("自定义")]264 public Color TextColor265 {266 get { return textColor; }267 set268 {269 textColor = value;270 Refresh();271 }272 }273 274 Rectangle m_rectWorking;
重绘
1 protected override void OnPaint(PaintEventArgs e) 2 { 3 base.OnPaint(e); 4 var g = e.Graphics; 5 g.SetGDIHigh(); 6 7 //外圆 8 float fltStartAngle = -90 - (meterDegrees) / 2 + 360; 9 var r1 = new Rectangle(m_rectWorking.Location, new Size(m_rectWorking.Width, m_rectWorking.Width));10 g.DrawArc(new Pen(new SolidBrush(externalRoundColor), 1), r1, fltStartAngle, meterDegrees);11 //内圆12 var r2 = new Rectangle(m_rectWorking.Left + (m_rectWorking.Width - m_rectWorking.Width / 4) / 2, m_rectWorking.Top + (m_rectWorking.Width - m_rectWorking.Width / 4) / 2, m_rectWorking.Width / 4, m_rectWorking.Width / 4);13 g.DrawArc(new Pen(new SolidBrush(insideRoundColor), 1), r2, fltStartAngle, meterDegrees);14 15 //边界线16 if (meterDegrees != 360)17 {18 float fltAngle = fltStartAngle - 180;19 20 float intY = (float)(m_rectWorking.Top + m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - m_rectWorking.Width / 8) * Math.Sin(Math.PI * (fltAngle / 180.00F))));21 float intX = (float)(m_rectWorking.Left + (m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - m_rectWorking.Width / 8) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));22 23 float fltY1 = (float)(m_rectWorking.Top + m_rectWorking.Width / 2 - (m_rectWorking.Width / 8 * Math.Sin(Math.PI * (fltAngle / 180.00F))));24 float fltX1 = (float)(m_rectWorking.Left + (m_rectWorking.Width / 2 - (m_rectWorking.Width / 8 * Math.Cos(Math.PI * (fltAngle / 180.00F)))));25 26 g.DrawLine(new Pen(new SolidBrush(boundaryLineColor), 1), new PointF(intX, intY), new PointF(fltX1, fltY1));27 g.DrawLine(new Pen(new SolidBrush(boundaryLineColor), 1), new PointF(m_rectWorking.Right - (fltX1 - m_rectWorking.Left), fltY1), new PointF(m_rectWorking.Right - (intX - m_rectWorking.Left), intY));28 }29 30 //分割线31 int _splitCount = splitCount * 2;32 float fltSplitValue = (float)meterDegrees / (float)_splitCount;33 for (int i = 0; i <= _splitCount; i++)34 {35 float fltAngle = (fltStartAngle + fltSplitValue * i - 180) % 360;36 float fltY1 = (float)(m_rectWorking.Top + m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2) * Math.Sin(Math.PI * (fltAngle / 180.00F))));37 float fltX1 = (float)(m_rectWorking.Left + (m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));38 float fltY2 = 0;39 float fltX2 = 0;40 if (i % 2 == 0)41 {42 fltY2 = (float)(m_rectWorking.Top + m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 10) * Math.Sin(Math.PI * (fltAngle / 180.00F))));43 fltX2 = (float)(m_rectWorking.Left + (m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 10) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));44 if (!(meterDegrees == 360 && i == _splitCount))45 {46 decimal decValue = minValue + (maxValue - minValue) / _splitCount * i;47 var txtSize = g.MeasureString(decValue.ToString("0.##"), this.Font);48 float fltFY1 = (float)(m_rectWorking.Top - txtSize.Height / 2 + m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 20) * Math.Sin(Math.PI * (fltAngle / 180.00F))));49 float fltFX1 = (float)(m_rectWorking.Left - txtSize.Width / 2 + (m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 20) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));50 g.DrawString(decValue.ToString("0.##"), Font, new SolidBrush(scaleValueColor), fltFX1, fltFY1);51 }52 }53 else54 {55 fltY2 = (float)(m_rectWorking.Top + m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 5) * Math.Sin(Math.PI * (fltAngle / 180.00F))));56 fltX2 = (float)(m_rectWorking.Left + (m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 5) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));57 }58 g.DrawLine(new Pen(new SolidBrush(scaleColor), i % 2 == 0 ? 2 : 1), new PointF(fltX1, fltY1), new PointF(fltX2, fltY2));59 }60 61 //值文字和固定文字62 if (textLocation != MeterTextLocation.None)63 {64 string str = m_value.ToString("0.##");65 var txtSize = g.MeasureString(str, textFont);66 float fltY = m_rectWorking.Top + m_rectWorking.Width / 4 - txtSize.Height / 2;67 float fltX = m_rectWorking.Left + m_rectWorking.Width / 2 - txtSize.Width / 2;68 g.DrawString(str, textFont, new SolidBrush(textColor), new PointF(fltX, fltY));69 70 if (!string.IsNullOrEmpty(fixedText))71 {72 str = fixedText;73 txtSize = g.MeasureString(str, textFont);74 fltY = m_rectWorking.Top + m_rectWorking.Width / 4 + txtSize.Height / 2;75 fltX = m_rectWorking.Left + m_rectWorking.Width / 2 - txtSize.Width / 2;76 g.DrawString(str, textFont, new SolidBrush(textColor), new PointF(fltX, fltY));77 }78 }79 80 //画指针81 g.FillEllipse(new SolidBrush(Color.FromArgb(100, pointerColor.R, pointerColor.G, pointerColor.B)), new Rectangle(m_rectWorking.Left + m_rectWorking.Width / 2 - 10, m_rectWorking.Top + m_rectWorking.Width / 2 - 10, 20, 20));82 g.FillEllipse(Brushes.Red, new Rectangle(m_rectWorking.Left + m_rectWorking.Width / 2 - 5, m_rectWorking.Top + m_rectWorking.Width / 2 - 5, 10, 10));83 float fltValueAngle = (fltStartAngle + ((float)(m_value - minValue) / (float)(maxValue - minValue)) * (float)meterDegrees - 180) % 360;84 float intValueY1 = (float)(m_rectWorking.Top + m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 30) * Math.Sin(Math.PI * (fltValueAngle / 180.00F))));85 float intValueX1 = (float)(m_rectWorking.Left + (m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 30) * Math.Cos(Math.PI * (fltValueAngle / 180.00F)))));86 g.DrawLine(new Pen(new SolidBrush(pointerColor), 3), intValueX1, intValueY1, m_rectWorking.Left + m_rectWorking.Width / 2, m_rectWorking.Top + m_rectWorking.Width / 2);87 }
还有一个显示文字位置的枚举
1 ///2 /// Enum MeterTextLocation 3 /// 4 public enum MeterTextLocation 5 { 6 ///7 /// The none 8 /// 9 None,10 ///11 /// The top12 /// 13 Top,14 ///15 /// The bottom16 /// 17 Bottom18 }
代码就这么多了,看完整代码
1 // *********************************************************************** 2 // Assembly : HZH_Controls 3 // Created : 2019-09-03 4 // 5 // *********************************************************************** 6 //7 // Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com 8 // 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 ///28 /// Class UCMeter. 29 /// Implements the 31 ///30 /// 32 public class UCMeter : UserControl 33 { 34 private int splitCount = 10; 35 /// 36 /// Gets or sets the split count. 37 /// 38 ///The split count. 39 [Description("分隔刻度数量,>1"), Category("自定义")] 40 public int SplitCount 41 { 42 get { return splitCount; } 43 set 44 { 45 if (value < 1) 46 return; 47 splitCount = value; 48 Refresh(); 49 } 50 } 51 52 private int meterDegrees = 150; 53 ///54 /// Gets or sets the meter degrees. 55 /// 56 ///The meter degrees. 57 [Description("表盘跨度角度,0-360"), Category("自定义")] 58 public int MeterDegrees 59 { 60 get { return meterDegrees; } 61 set 62 { 63 if (value > 360 || value <= 0) 64 return; 65 meterDegrees = value; 66 Refresh(); 67 } 68 } 69 70 private decimal minValue = 0; 71 ///72 /// Gets or sets the minimum value. 73 /// 74 ///The minimum value. 75 [Description("最小值,= maxValue) 82 return; 83 minValue = value; 84 Refresh(); 85 } 86 } 87 88 private decimal maxValue = 100; 89 /// 90 /// Gets or sets the maximum value. 91 /// 92 ///The maximum value. 93 [Description("最大值,>MinValue"), Category("自定义")] 94 public decimal MaxValue 95 { 96 get { return maxValue; } 97 set 98 { 99 if (value <= minValue)100 return;101 maxValue = value;102 Refresh();103 }104 }105 ///106 /// 获取或设置控件显示的文字的字体。107 /// 108 ///The font. 109 ///110 /// 115 [Description("刻度字体"), Category("自定义")]116 public override Font Font117 {118 get119 {120 return base.Font;121 }122 set123 {124 base.Font = value;125 Refresh();126 }127 }128 129 private decimal m_value = 0;130 ///111 /// 112 /// 113 /// 114 /// 131 /// Gets or sets the value.132 /// 133 ///The value. 134 [Description("值,>=MinValue并且<=MaxValue"), Category("自定义")]135 public decimal Value136 {137 get { return m_value; }138 set139 {140 if (value < minValue || value > maxValue)141 return;142 m_value = value;143 Refresh();144 }145 }146 147 private MeterTextLocation textLocation = MeterTextLocation.None;148 ///149 /// Gets or sets the text location.150 /// 151 ///The text location. 152 [Description("值和固定文字显示位置"), Category("自定义")]153 public MeterTextLocation TextLocation154 {155 get { return textLocation; }156 set157 {158 textLocation = value;159 Refresh();160 }161 }162 163 private string fixedText;164 ///165 /// Gets or sets the fixed text.166 /// 167 ///The fixed text. 168 [Description("固定文字"), Category("自定义")]169 public string FixedText170 {171 get { return fixedText; }172 set173 {174 fixedText = value;175 Refresh();176 }177 }178 179 private Font textFont = DefaultFont;180 ///181 /// Gets or sets the text font.182 /// 183 ///The text font. 184 [Description("值和固定文字字体"), Category("自定义")]185 public Font TextFont186 {187 get { return textFont; }188 set189 {190 textFont = value;191 Refresh();192 }193 }194 195 private Color externalRoundColor = Color.FromArgb(255, 77, 59);196 ///197 /// Gets or sets the color of the external round.198 /// 199 ///The color of the external round. 200 [Description("外圆颜色"), Category("自定义")]201 public Color ExternalRoundColor202 {203 get { return externalRoundColor; }204 set205 {206 externalRoundColor = value;207 Refresh();208 }209 }210 211 private Color insideRoundColor = Color.FromArgb(255, 77, 59);212 ///213 /// Gets or sets the color of the inside round.214 /// 215 ///The color of the inside round. 216 [Description("内圆颜色"), Category("自定义")]217 public Color InsideRoundColor218 {219 get { return insideRoundColor; }220 set221 {222 insideRoundColor = value;223 Refresh();224 }225 }226 227 private Color boundaryLineColor = Color.FromArgb(255, 77, 59);228 ///229 /// Gets or sets the color of the boundary line.230 /// 231 ///The color of the boundary line. 232 [Description("边界线颜色"), Category("自定义")]233 public Color BoundaryLineColor234 {235 get { return boundaryLineColor; }236 set237 {238 boundaryLineColor = value;239 Refresh();240 }241 }242 243 private Color scaleColor = Color.FromArgb(255, 77, 59);244 ///245 /// Gets or sets the color of the scale.246 /// 247 ///The color of the scale. 248 [Description("刻度颜色"), Category("自定义")]249 public Color ScaleColor250 {251 get { return scaleColor; }252 set253 {254 scaleColor = value;255 Refresh();256 }257 }258 259 private Color scaleValueColor = Color.FromArgb(255, 77, 59);260 ///261 /// Gets or sets the color of the scale value.262 /// 263 ///The color of the scale value. 264 [Description("刻度值文字颜色"), Category("自定义")]265 public Color ScaleValueColor266 {267 get { return scaleValueColor; }268 set269 {270 scaleValueColor = value;271 Refresh();272 }273 }274 275 private Color pointerColor = Color.FromArgb(255, 77, 59);276 ///277 /// Gets or sets the color of the pointer.278 /// 279 ///The color of the pointer. 280 [Description("指针颜色"), Category("自定义")]281 public Color PointerColor282 {283 get { return pointerColor; }284 set285 {286 pointerColor = value;287 Refresh();288 }289 }290 291 private Color textColor = Color.FromArgb(255, 77, 59);292 ///293 /// Gets or sets the color of the text.294 /// 295 ///The color of the text. 296 [Description("值和固定文字颜色"), Category("自定义")]297 public Color TextColor298 {299 get { return textColor; }300 set301 {302 textColor = value;303 Refresh();304 }305 }306 307 Rectangle m_rectWorking;308 public UCMeter()309 {310 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);311 this.SetStyle(ControlStyles.DoubleBuffer, true);312 this.SetStyle(ControlStyles.ResizeRedraw, true);313 this.SetStyle(ControlStyles.Selectable, true);314 this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);315 this.SetStyle(ControlStyles.UserPaint, true);316 this.SizeChanged += UCMeter1_SizeChanged;317 this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;318 this.Size = new Size(350, 200);319 }320 321 void UCMeter1_SizeChanged(object sender, EventArgs e)322 {323 m_rectWorking = new Rectangle(10, 10, this.Width - 20, this.Height - 20);324 }325 326 327 protected override void OnPaint(PaintEventArgs e)328 {329 base.OnPaint(e);330 var g = e.Graphics;331 g.SetGDIHigh();332 333 //外圆334 float fltStartAngle = -90 - (meterDegrees) / 2 + 360;335 var r1 = new Rectangle(m_rectWorking.Location, new Size(m_rectWorking.Width, m_rectWorking.Width));336 g.DrawArc(new Pen(new SolidBrush(externalRoundColor), 1), r1, fltStartAngle, meterDegrees);337 //内圆338 var r2 = new Rectangle(m_rectWorking.Left + (m_rectWorking.Width - m_rectWorking.Width / 4) / 2, m_rectWorking.Top + (m_rectWorking.Width - m_rectWorking.Width / 4) / 2, m_rectWorking.Width / 4, m_rectWorking.Width / 4);339 g.DrawArc(new Pen(new SolidBrush(insideRoundColor), 1), r2, fltStartAngle, meterDegrees);340 341 //边界线342 if (meterDegrees != 360)343 {344 float fltAngle = fltStartAngle - 180;345 346 float intY = (float)(m_rectWorking.Top + m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - m_rectWorking.Width / 8) * Math.Sin(Math.PI * (fltAngle / 180.00F))));347 float intX = (float)(m_rectWorking.Left + (m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - m_rectWorking.Width / 8) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));348 349 float fltY1 = (float)(m_rectWorking.Top + m_rectWorking.Width / 2 - (m_rectWorking.Width / 8 * Math.Sin(Math.PI * (fltAngle / 180.00F))));350 float fltX1 = (float)(m_rectWorking.Left + (m_rectWorking.Width / 2 - (m_rectWorking.Width / 8 * Math.Cos(Math.PI * (fltAngle / 180.00F)))));351 352 g.DrawLine(new Pen(new SolidBrush(boundaryLineColor), 1), new PointF(intX, intY), new PointF(fltX1, fltY1));353 g.DrawLine(new Pen(new SolidBrush(boundaryLineColor), 1), new PointF(m_rectWorking.Right - (fltX1 - m_rectWorking.Left), fltY1), new PointF(m_rectWorking.Right - (intX - m_rectWorking.Left), intY));354 }355 356 //分割线357 int _splitCount = splitCount * 2;358 float fltSplitValue = (float)meterDegrees / (float)_splitCount;359 for (int i = 0; i <= _splitCount; i++)360 {361 float fltAngle = (fltStartAngle + fltSplitValue * i - 180) % 360;362 float fltY1 = (float)(m_rectWorking.Top + m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2) * Math.Sin(Math.PI * (fltAngle / 180.00F))));363 float fltX1 = (float)(m_rectWorking.Left + (m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));364 float fltY2 = 0;365 float fltX2 = 0;366 if (i % 2 == 0)367 {368 fltY2 = (float)(m_rectWorking.Top + m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 10) * Math.Sin(Math.PI * (fltAngle / 180.00F))));369 fltX2 = (float)(m_rectWorking.Left + (m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 10) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));370 if (!(meterDegrees == 360 && i == _splitCount))371 {372 decimal decValue = minValue + (maxValue - minValue) / _splitCount * i;373 var txtSize = g.MeasureString(decValue.ToString("0.##"), this.Font);374 float fltFY1 = (float)(m_rectWorking.Top - txtSize.Height / 2 + m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 20) * Math.Sin(Math.PI * (fltAngle / 180.00F))));375 float fltFX1 = (float)(m_rectWorking.Left - txtSize.Width / 2 + (m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 20) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));376 g.DrawString(decValue.ToString("0.##"), Font, new SolidBrush(scaleValueColor), fltFX1, fltFY1);377 }378 }379 else380 {381 fltY2 = (float)(m_rectWorking.Top + m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 5) * Math.Sin(Math.PI * (fltAngle / 180.00F))));382 fltX2 = (float)(m_rectWorking.Left + (m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 5) * Math.Cos(Math.PI * (fltAngle / 180.00F)))));383 }384 g.DrawLine(new Pen(new SolidBrush(scaleColor), i % 2 == 0 ? 2 : 1), new PointF(fltX1, fltY1), new PointF(fltX2, fltY2));385 }386 387 //值文字和固定文字388 if (textLocation != MeterTextLocation.None)389 {390 string str = m_value.ToString("0.##");391 var txtSize = g.MeasureString(str, textFont);392 float fltY = m_rectWorking.Top + m_rectWorking.Width / 4 - txtSize.Height / 2;393 float fltX = m_rectWorking.Left + m_rectWorking.Width / 2 - txtSize.Width / 2;394 g.DrawString(str, textFont, new SolidBrush(textColor), new PointF(fltX, fltY));395 396 if (!string.IsNullOrEmpty(fixedText))397 {398 str = fixedText;399 txtSize = g.MeasureString(str, textFont);400 fltY = m_rectWorking.Top + m_rectWorking.Width / 4 + txtSize.Height / 2;401 fltX = m_rectWorking.Left + m_rectWorking.Width / 2 - txtSize.Width / 2;402 g.DrawString(str, textFont, new SolidBrush(textColor), new PointF(fltX, fltY));403 }404 }405 406 //画指针407 g.FillEllipse(new SolidBrush(Color.FromArgb(100, pointerColor.R, pointerColor.G, pointerColor.B)), new Rectangle(m_rectWorking.Left + m_rectWorking.Width / 2 - 10, m_rectWorking.Top + m_rectWorking.Width / 2 - 10, 20, 20));408 g.FillEllipse(Brushes.Red, new Rectangle(m_rectWorking.Left + m_rectWorking.Width / 2 - 5, m_rectWorking.Top + m_rectWorking.Width / 2 - 5, 10, 10));409 float fltValueAngle = (fltStartAngle + ((float)(m_value - minValue) / (float)(maxValue - minValue)) * (float)meterDegrees - 180) % 360;410 float intValueY1 = (float)(m_rectWorking.Top + m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 30) * Math.Sin(Math.PI * (fltValueAngle / 180.00F))));411 float intValueX1 = (float)(m_rectWorking.Left + (m_rectWorking.Width / 2 - ((m_rectWorking.Width / 2 - 30) * Math.Cos(Math.PI * (fltValueAngle / 180.00F)))));412 g.DrawLine(new Pen(new SolidBrush(pointerColor), 3), intValueX1, intValueY1, m_rectWorking.Left + m_rectWorking.Width / 2, m_rectWorking.Top + m_rectWorking.Width / 2);413 }414 }415 416 ///417 /// Enum MeterTextLocation418 /// 419 public enum MeterTextLocation420 {421 ///422 /// The none423 /// 424 None,425 ///426 /// The top427 /// 428 Top,429 ///430 /// The bottom431 /// 432 Bottom433 }434 }
如果你喜欢的话,请到 点个星星吧