(五十四)c#Winform自定义控件-仪表盘

前提

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

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

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

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

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

NuGet

Install-Package HZH_Controls

目录

https://www.cnblogs.com/bfyx/p/11364884.html

用处及效果

(五十四)c#Winform自定义控件-仪表盘_第1张图片

准备工作

依然使用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("最小值,"), Category("自定义")]
 43         public decimal MinValue
 44         {
 45             get { return minValue; }
 46             set
 47             {
 48                 if (value >= 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         ///   
 78         ///   
 79         ///   
 80         ///   
 81         /// 
 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         /// 
 98         /// Gets or sets the value.
 99         /// 
100         /// The value.
101         [Description("值,>=MinValue并且<=MaxValue"), Category("自定义")]
102         public decimal Value
103         {
104             get { return m_value; }
105             set
106             {
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 TextLocation
121         {
122             get { return textLocation; }
123             set
124             {
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 FixedText
137         {
138             get { return fixedText; }
139             set
140             {
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 TextFont
153         {
154             get { return textFont; }
155             set
156             {
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 ExternalRoundColor
169         {
170             get { return externalRoundColor; }
171             set
172             {
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 InsideRoundColor
185         {
186             get { return insideRoundColor; }
187             set
188             {
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 BoundaryLineColor
201         {
202             get { return boundaryLineColor; }
203             set
204             {
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 ScaleColor
217         {
218             get { return scaleColor; }
219             set
220             {
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 ScaleValueColor
233         {
234             get { return scaleValueColor; }
235             set
236             {
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 PointerColor
249         {
250             get { return pointerColor; }
251             set
252             {
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 TextColor
265         {
266             get { return textColor; }
267             set
268             {
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                 else
54                 {
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 top
12         /// 
13         Top,
14         /// 
15         /// The bottom
16         /// 
17         Bottom
18     }

代码就这么多了,看完整代码

  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:[email protected]
  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 
 30     /// 
 31     /// 
 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("最小值,"), Category("自定义")]
 76         public decimal MinValue
 77         {
 78             get { return minValue; }
 79             set
 80             {
 81                 if (value >= 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         ///   
111         ///   
112         ///   
113         ///   
114         /// 
115         [Description("刻度字体"), Category("自定义")]
116         public override Font Font
117         {
118             get
119             {
120                 return base.Font;
121             }
122             set
123             {
124                 base.Font = value;
125                 Refresh();
126             }
127         }
128 
129         private decimal m_value = 0;
130         /// 
131         /// Gets or sets the value.
132         /// 
133         /// The value.
134         [Description("值,>=MinValue并且<=MaxValue"), Category("自定义")]
135         public decimal Value
136         {
137             get { return m_value; }
138             set
139             {
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 TextLocation
154         {
155             get { return textLocation; }
156             set
157             {
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 FixedText
170         {
171             get { return fixedText; }
172             set
173             {
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 TextFont
186         {
187             get { return textFont; }
188             set
189             {
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 ExternalRoundColor
202         {
203             get { return externalRoundColor; }
204             set
205             {
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 InsideRoundColor
218         {
219             get { return insideRoundColor; }
220             set
221             {
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 BoundaryLineColor
234         {
235             get { return boundaryLineColor; }
236             set
237             {
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 ScaleColor
250         {
251             get { return scaleColor; }
252             set
253             {
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 ScaleValueColor
266         {
267             get { return scaleValueColor; }
268             set
269             {
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 PointerColor
282         {
283             get { return pointerColor; }
284             set
285             {
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 TextColor
298         {
299             get { return textColor; }
300             set
301             {
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                 else
380                 {
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 MeterTextLocation
418     /// 
419     public enum MeterTextLocation
420     {
421         /// 
422         /// The none
423         /// 
424         None,
425         /// 
426         /// The top
427         /// 
428         Top,
429         /// 
430         /// The bottom
431         /// 
432         Bottom
433     }
434 }
View Code

 

 

最后的话

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧

你可能感兴趣的:((五十四)c#Winform自定义控件-仪表盘)