当前位置: 移动技术网 > IT编程>开发语言>.net > (五十四)c#Winform自定义控件-仪表盘

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

2019年09月04日  | 移动技术网IT编程  | 我要评论

有阴气动漫网,怎么提高电脑速度,联想手提电脑报价

前提

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

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

码云:

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

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

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

nuget

install-package hzh_controls

目录

用处及效果

准备工作

依然使用gdi+画的,不懂的话就百度一下吧

另外主要用到了三角函数,如果不懂,可以向初中的数学老师再问问(你也可以百度一下)

开始

添加一个类ucmeter 继承 usercontrol

首先添加一个需要控制的属性

  1 private int splitcount = 10;
  2         /// <summary>
  3         /// gets or sets the split count.
  4         /// </summary>
  5         /// <value>the split count.</value>
  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         /// <summary>
 21         /// gets or sets the meter degrees.
 22         /// </summary>
 23         /// <value>the meter degrees.</value>
 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         /// <summary>
 39         /// gets or sets the minimum value.
 40         /// </summary>
 41         /// <value>the minimum value.</value>
 42         [description("最小值,<maxvalue"), 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         /// <summary>
 57         /// gets or sets the maximum value.
 58         /// </summary>
 59         /// <value>the maximum value.</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         /// <summary>
 73         /// 获取或设置控件显示的文字的字体。
 74         /// </summary>
 75         /// <value>the font.</value>
 76         /// <permissionset>
 77         ///   <ipermission class="system.security.permissions.environmentpermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
 78         ///   <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
 79         ///   <ipermission class="system.security.permissions.securitypermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" flags="unmanagedcode, controlevidence" />
 80         ///   <ipermission class="system.diagnostics.performancecounterpermission, system, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
 81         /// </permissionset>
 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         /// <summary>
 98         /// gets or sets the value.
 99         /// </summary>
100         /// <value>the value.</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         /// <summary>
116         /// gets or sets the text location.
117         /// </summary>
118         /// <value>the text location.</value>
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         /// <summary>
132         /// gets or sets the fixed text.
133         /// </summary>
134         /// <value>the fixed text.</value>
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         /// <summary>
148         /// gets or sets the text font.
149         /// </summary>
150         /// <value>the text font.</value>
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         /// <summary>
164         /// gets or sets the color of the external round.
165         /// </summary>
166         /// <value>the color of the external round.</value>
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         /// <summary>
180         /// gets or sets the color of the inside round.
181         /// </summary>
182         /// <value>the color of the inside round.</value>
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         /// <summary>
196         /// gets or sets the color of the boundary line.
197         /// </summary>
198         /// <value>the color of the boundary line.</value>
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         /// <summary>
212         /// gets or sets the color of the scale.
213         /// </summary>
214         /// <value>the color of the scale.</value>
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         /// <summary>
228         /// gets or sets the color of the scale value.
229         /// </summary>
230         /// <value>the color of the scale value.</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         /// <summary>
244         /// gets or sets the color of the pointer.
245         /// </summary>
246         /// <value>the color of the pointer.</value>
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         /// <summary>
260         /// gets or sets the color of the text.
261         /// </summary>
262         /// <value>the color of the text.</value>
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 /// <summary>
 2     /// enum metertextlocation
 3     /// </summary>
 4     public enum metertextlocation
 5     {
 6         /// <summary>
 7         /// the none
 8         /// </summary>
 9         none,
10         /// <summary>
11         /// the top
12         /// </summary>
13         top,
14         /// <summary>
15         /// the bottom
16         /// </summary>
17         bottom
18     }

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

  1 // ***********************************************************************
  2 // assembly         : hzh_controls
  3 // created          : 2019-09-03
  4 //
  5 // ***********************************************************************
  6 // <copyright file="ucmeter.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 ucmeter.
 29     /// implements the <see cref="system.windows.forms.usercontrol" />
 30     /// </summary>
 31     /// <seealso cref="system.windows.forms.usercontrol" />
 32     public class ucmeter : usercontrol
 33     {
 34         private int splitcount = 10;
 35         /// <summary>
 36         /// gets or sets the split count.
 37         /// </summary>
 38         /// <value>the split count.</value>
 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         /// <summary>
 54         /// gets or sets the meter degrees.
 55         /// </summary>
 56         /// <value>the meter degrees.</value>
 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         /// <summary>
 72         /// gets or sets the minimum value.
 73         /// </summary>
 74         /// <value>the minimum value.</value>
 75         [description("最小值,<maxvalue"), 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         /// <summary>
 90         /// gets or sets the maximum value.
 91         /// </summary>
 92         /// <value>the maximum value.</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         /// <summary>
106         /// 获取或设置控件显示的文字的字体。
107         /// </summary>
108         /// <value>the font.</value>
109         /// <permissionset>
110         ///   <ipermission class="system.security.permissions.environmentpermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
111         ///   <ipermission class="system.security.permissions.fileiopermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
112         ///   <ipermission class="system.security.permissions.securitypermission, mscorlib, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" flags="unmanagedcode, controlevidence" />
113         ///   <ipermission class="system.diagnostics.performancecounterpermission, system, version=2.0.3600.0, culture=neutral, publickeytoken=b77a5c561934e089" version="1" unrestricted="true" />
114         /// </permissionset>
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         /// <summary>
131         /// gets or sets the value.
132         /// </summary>
133         /// <value>the value.</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         /// <summary>
149         /// gets or sets the text location.
150         /// </summary>
151         /// <value>the text location.</value>
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         /// <summary>
165         /// gets or sets the fixed text.
166         /// </summary>
167         /// <value>the fixed text.</value>
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         /// <summary>
181         /// gets or sets the text font.
182         /// </summary>
183         /// <value>the text font.</value>
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         /// <summary>
197         /// gets or sets the color of the external round.
198         /// </summary>
199         /// <value>the color of the external round.</value>
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         /// <summary>
213         /// gets or sets the color of the inside round.
214         /// </summary>
215         /// <value>the color of the inside round.</value>
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         /// <summary>
229         /// gets or sets the color of the boundary line.
230         /// </summary>
231         /// <value>the color of the boundary line.</value>
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         /// <summary>
245         /// gets or sets the color of the scale.
246         /// </summary>
247         /// <value>the color of the scale.</value>
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         /// <summary>
261         /// gets or sets the color of the scale value.
262         /// </summary>
263         /// <value>the color of the scale value.</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         /// <summary>
277         /// gets or sets the color of the pointer.
278         /// </summary>
279         /// <value>the color of the pointer.</value>
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         /// <summary>
293         /// gets or sets the color of the text.
294         /// </summary>
295         /// <value>the color of the text.</value>
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     /// <summary>
417     /// enum metertextlocation
418     /// </summary>
419     public enum metertextlocation
420     {
421         /// <summary>
422         /// the none
423         /// </summary>
424         none,
425         /// <summary>
426         /// the top
427         /// </summary>
428         top,
429         /// <summary>
430         /// the bottom
431         /// </summary>
432         bottom
433     }
434 }

 

 

最后的话

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

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网