当前位置: 移动技术网 > IT编程>开发语言>.net > (三十八)c#Winform自定义控件-圆形进度条

(三十八)c#Winform自定义控件-圆形进度条

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

任仲平,浮现你的脸音译歌词,切尔西vs曼联直播吧

前提

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

开源地址:

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

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

目录

准备工作

我们理一下思路,进度条支持圆环或扇形显示,支持百分比和数值显示

开始

添加一个用户控件,命名ucprocessellipse

定义2个枚举

 1  public enum valuetype
 2     {
 3         /// <summary>
 4         /// 百分比
 5         /// </summary>
 6         percent,
 7         /// <summary>
 8         /// 数值
 9         /// </summary>
10         absolute
11     }
12 
13     public enum showtype
14     {
15         /// <summary>
16         /// 圆环
17         /// </summary>
18         ring,
19         /// <summary>
20         /// 扇形
21         /// </summary>
22         sector
23     }

 

添加属性

  1  [description("值改变事件"), category("自定义")]
  2         public event eventhandler valuechanged;
  3 
  4         private color m_backellipsecolor = color.fromargb(22, 160, 133);
  5         /// <summary>
  6         /// 圆背景色
  7         /// </summary>
  8         [description("圆背景色"), category("自定义")]
  9         public color backellipsecolor
 10         {
 11             get { return m_backellipsecolor; }
 12             set
 13             {
 14                 m_backellipsecolor = value;
 15                 refresh();
 16             }
 17         }
 18 
 19         private color m_coreellipsecolor = color.fromargb(180, 180, 180);
 20         /// <summary>
 21         /// 内圆颜色,showtype=ring 有效
 22         /// </summary>
 23         [description("内圆颜色,showtype=ring 有效"), category("自定义")]
 24         public color coreellipsecolor
 25         {
 26             get { return m_coreellipsecolor; }
 27             set
 28             {
 29                 m_coreellipsecolor = value;
 30                 refresh();
 31             }
 32         }
 33 
 34         private color m_valuecolor = color.fromargb(255, 77, 59);
 35 
 36         [description("值圆颜色"), category("自定义")]
 37         public color valuecolor
 38         {
 39             get { return m_valuecolor; }
 40             set
 41             {
 42                 m_valuecolor = value;
 43                 refresh();
 44             }
 45         }
 46 
 47         private bool m_isshowcoreellipseborder = true;
 48         /// <summary>
 49         /// 内圆是否显示边框,showtype=ring 有效
 50         /// </summary>
 51         [description("内圆是否显示边框,showtype=ring 有效"), category("自定义")]
 52         public bool isshowcoreellipseborder
 53         {
 54             get { return m_isshowcoreellipseborder; }
 55             set
 56             {
 57                 m_isshowcoreellipseborder = value;
 58                 refresh();
 59             }
 60         }
 61 
 62         private valuetype m_valuetype = valuetype.percent;
 63         /// <summary>
 64         /// 值文字类型
 65         /// </summary>
 66         [description("值文字类型"), category("自定义")]
 67         public valuetype valuetype
 68         {
 69             get { return m_valuetype; }
 70             set
 71             {
 72                 m_valuetype = value;
 73                 refresh();
 74             }
 75         }
 76 
 77         private int m_valuewidth = 30;
 78         /// <summary>
 79         /// 外圆值宽度
 80         /// </summary>
 81         [description("外圆值宽度,showtype=ring 有效"), category("自定义")]
 82         public int valuewidth
 83         {
 84             get { return m_valuewidth; }
 85             set
 86             {
 87                 if (value <= 0 || value > math.min(this.width, this.height))
 88                     return;
 89                 m_valuewidth = value;
 90                 refresh();
 91             }
 92         }
 93 
 94         private int m_valuemargin = 5;
 95         /// <summary>
 96         /// 外圆值间距
 97         /// </summary>
 98         [description("外圆值间距"), category("自定义")]
 99         public int valuemargin
100         {
101             get { return m_valuemargin; }
102             set
103             {
104                 if (value < 0 || m_valuemargin >= m_valuewidth)
105                     return;
106                 m_valuemargin = value;
107                 refresh();
108             }
109         }
110 
111         private int m_maxvalue = 100;
112         /// <summary>
113         /// 最大值
114         /// </summary>
115         [description("最大值"), category("自定义")]
116         public int maxvalue
117         {
118             get { return m_maxvalue; }
119             set
120             {
121                 if (value > m_value || value <= 0)
122                     return;
123                 m_maxvalue = value;
124                 refresh();
125             }
126         }
127 
128         private int m_value = 0;
129         /// <summary>
130         /// 当前值
131         /// </summary>
132         [description("当前值"), category("自定义")]
133         public int value
134         {
135             get { return m_value; }
136             set
137             {
138                 if (m_maxvalue < value || value <= 0)
139                     return;
140                 m_value = value;
141                 if (valuechanged != null)
142                 {
143                     valuechanged(this, null);
144                 }
145                 refresh();
146             }
147         }
148         private font m_font = new font("arial unicode ms", 20);
149         [description("文字字体"), category("自定义")]
150         public override font font
151         {
152             get
153             {
154                 return m_font;
155             }
156             set
157             {
158                 m_font = value;
159                 refresh();
160             }
161         }
162         color m_forecolor = color.white;
163         [description("文字颜色"), category("自定义")]
164         public override color forecolor
165         {
166             get
167             {
168                 return m_forecolor;
169             }
170             set
171             {
172                 m_forecolor = value;
173                 refresh();
174             }
175         }
176 
177         private showtype m_showtype = showtype.ring;
178 
179         [description("显示类型"), category("自定义")]
180         public showtype showtype
181         {
182             get { return m_showtype; }
183             set
184             {
185                 m_showtype = value;
186                 refresh();
187             }
188         }

重绘

 1   protected override void onpaint(painteventargs e)
 2         {
 3             base.onpaint(e);
 4 
 5             var g = e.graphics;
 6             g.smoothingmode = smoothingmode.antialias;  //使绘图质量最高,即消除锯齿
 7             g.interpolationmode = interpolationmode.highqualitybicubic;
 8             g.compositingquality = compositingquality.highquality;
 9 
10             int intwidth = math.min(this.size.width, this.size.height);
11             //底圆
12             g.fillellipse(new solidbrush(m_backellipsecolor), new rectangle(new point(0, 0), new size(intwidth, intwidth)));
13             if (m_showtype == hzh_controls.controls.showtype.ring)
14             {
15                 //中心圆
16                 int intcore = intwidth - m_valuewidth * 2;
17                 g.fillellipse(new solidbrush(m_coreellipsecolor), new rectangle(new point(m_valuewidth, m_valuewidth), new size(intcore, intcore)));
18                 //中心圆边框
19                 if (m_isshowcoreellipseborder)
20                 {
21                     g.drawellipse(new pen(m_valuecolor, 2), new rectangle(new point(m_valuewidth + 1, m_valuewidth + 1), new size(intcore - 1, intcore - 1)));
22                 }
23                 if (m_value > 0 && m_maxvalue > 0)
24                 {
25                     float fltpercent = (float)m_value / (float)m_maxvalue;
26                     if (fltpercent > 1)
27                     {
28                         fltpercent = 1;
29                     }
30 
31                     g.drawarc(new pen(m_valuecolor, m_valuewidth - m_valuemargin * 2), new rectanglef(new point(m_valuewidth / 2 + m_valuemargin / 4, m_valuewidth / 2 + m_valuemargin / 4), new sizef(intwidth - m_valuewidth - m_valuemargin / 2 + (m_valuemargin == 0 ? 0 : 1), intwidth - m_valuewidth - m_valuemargin / 2 + (m_valuemargin == 0 ? 0 : 1))), -90, fltpercent * 360);
32 
33                     string strvaluetext = m_valuetype == hzh_controls.controls.valuetype.percent ? fltpercent.tostring("0%") : m_value.tostring();
34                     system.drawing.sizef _txtsize = g.measurestring(strvaluetext, this.font);
35                     g.drawstring(strvaluetext, this.font, new solidbrush(this.forecolor), new pointf((intwidth - _txtsize.width) / 2 + 1, (intwidth - _txtsize.height) / 2 + 1));
36                 }
37             }
38             else
39             {
40                 if (m_value > 0 && m_maxvalue > 0)
41                 {
42                     float fltpercent = (float)m_value / (float)m_maxvalue;
43                     if (fltpercent > 1)
44                     {
45                         fltpercent = 1;
46                     }
47 
48                     g.fillpie(new solidbrush(m_valuecolor), new rectangle(m_valuemargin, m_valuemargin, intwidth - m_valuemargin * 2, intwidth - m_valuemargin * 2), -90, fltpercent * 360);
49 
50                     string strvaluetext = m_valuetype == hzh_controls.controls.valuetype.percent ? fltpercent.tostring("0%") : m_value.tostring();
51                     system.drawing.sizef _txtsize = g.measurestring(strvaluetext, this.font);
52                     g.drawstring(strvaluetext, this.font, new solidbrush(this.forecolor), new pointf((intwidth - _txtsize.width) / 2 + 1, (intwidth - _txtsize.height) / 2 + 1));
53                 }
54             }
55 
56         }

完整代码如下

  1 using system;
  2 using system.collections.generic;
  3 using system.componentmodel;
  4 using system.drawing;
  5 using system.data;
  6 using system.linq;
  7 using system.text;
  8 using system.windows.forms;
  9 using system.drawing.drawing2d;
 10 
 11 namespace hzh_controls.controls
 12 {
 13     public partial class ucprocessellipse : usercontrol
 14     {
 15         [description("值改变事件"), category("自定义")]
 16         public event eventhandler valuechanged;
 17 
 18         private color m_backellipsecolor = color.fromargb(22, 160, 133);
 19         /// <summary>
 20         /// 圆背景色
 21         /// </summary>
 22         [description("圆背景色"), category("自定义")]
 23         public color backellipsecolor
 24         {
 25             get { return m_backellipsecolor; }
 26             set
 27             {
 28                 m_backellipsecolor = value;
 29                 refresh();
 30             }
 31         }
 32 
 33         private color m_coreellipsecolor = color.fromargb(180, 180, 180);
 34         /// <summary>
 35         /// 内圆颜色,showtype=ring 有效
 36         /// </summary>
 37         [description("内圆颜色,showtype=ring 有效"), category("自定义")]
 38         public color coreellipsecolor
 39         {
 40             get { return m_coreellipsecolor; }
 41             set
 42             {
 43                 m_coreellipsecolor = value;
 44                 refresh();
 45             }
 46         }
 47 
 48         private color m_valuecolor = color.fromargb(255, 77, 59);
 49 
 50         [description("值圆颜色"), category("自定义")]
 51         public color valuecolor
 52         {
 53             get { return m_valuecolor; }
 54             set
 55             {
 56                 m_valuecolor = value;
 57                 refresh();
 58             }
 59         }
 60 
 61         private bool m_isshowcoreellipseborder = true;
 62         /// <summary>
 63         /// 内圆是否显示边框,showtype=ring 有效
 64         /// </summary>
 65         [description("内圆是否显示边框,showtype=ring 有效"), category("自定义")]
 66         public bool isshowcoreellipseborder
 67         {
 68             get { return m_isshowcoreellipseborder; }
 69             set
 70             {
 71                 m_isshowcoreellipseborder = value;
 72                 refresh();
 73             }
 74         }
 75 
 76         private valuetype m_valuetype = valuetype.percent;
 77         /// <summary>
 78         /// 值文字类型
 79         /// </summary>
 80         [description("值文字类型"), category("自定义")]
 81         public valuetype valuetype
 82         {
 83             get { return m_valuetype; }
 84             set
 85             {
 86                 m_valuetype = value;
 87                 refresh();
 88             }
 89         }
 90 
 91         private int m_valuewidth = 30;
 92         /// <summary>
 93         /// 外圆值宽度
 94         /// </summary>
 95         [description("外圆值宽度,showtype=ring 有效"), category("自定义")]
 96         public int valuewidth
 97         {
 98             get { return m_valuewidth; }
 99             set
100             {
101                 if (value <= 0 || value > math.min(this.width, this.height))
102                     return;
103                 m_valuewidth = value;
104                 refresh();
105             }
106         }
107 
108         private int m_valuemargin = 5;
109         /// <summary>
110         /// 外圆值间距
111         /// </summary>
112         [description("外圆值间距"), category("自定义")]
113         public int valuemargin
114         {
115             get { return m_valuemargin; }
116             set
117             {
118                 if (value < 0 || m_valuemargin >= m_valuewidth)
119                     return;
120                 m_valuemargin = value;
121                 refresh();
122             }
123         }
124 
125         private int m_maxvalue = 100;
126         /// <summary>
127         /// 最大值
128         /// </summary>
129         [description("最大值"), category("自定义")]
130         public int maxvalue
131         {
132             get { return m_maxvalue; }
133             set
134             {
135                 if (value > m_value || value <= 0)
136                     return;
137                 m_maxvalue = value;
138                 refresh();
139             }
140         }
141 
142         private int m_value = 0;
143         /// <summary>
144         /// 当前值
145         /// </summary>
146         [description("当前值"), category("自定义")]
147         public int value
148         {
149             get { return m_value; }
150             set
151             {
152                 if (m_maxvalue < value || value <= 0)
153                     return;
154                 m_value = value;
155                 if (valuechanged != null)
156                 {
157                     valuechanged(this, null);
158                 }
159                 refresh();
160             }
161         }
162         private font m_font = new font("arial unicode ms", 20);
163         [description("文字字体"), category("自定义")]
164         public override font font
165         {
166             get
167             {
168                 return m_font;
169             }
170             set
171             {
172                 m_font = value;
173                 refresh();
174             }
175         }
176         color m_forecolor = color.white;
177         [description("文字颜色"), category("自定义")]
178         public override color forecolor
179         {
180             get
181             {
182                 return m_forecolor;
183             }
184             set
185             {
186                 m_forecolor = value;
187                 refresh();
188             }
189         }
190 
191         private showtype m_showtype = showtype.ring;
192 
193         [description("显示类型"), category("自定义")]
194         public showtype showtype
195         {
196             get { return m_showtype; }
197             set
198             {
199                 m_showtype = value;
200                 refresh();
201             }
202         }
203 
204         public ucprocessellipse()
205         {
206             initializecomponent();
207             this.setstyle(controlstyles.allpaintinginwmpaint, true);
208             this.setstyle(controlstyles.doublebuffer, true);
209             this.setstyle(controlstyles.resizeredraw, true);
210             this.setstyle(controlstyles.selectable, true);
211             this.setstyle(controlstyles.supportstransparentbackcolor, true);
212             this.setstyle(controlstyles.userpaint, true);
213         }
214 
215         protected override void onpaint(painteventargs e)
216         {
217             base.onpaint(e);
218 
219             var g = e.graphics;
220             g.smoothingmode = smoothingmode.antialias;  //使绘图质量最高,即消除锯齿
221             g.interpolationmode = interpolationmode.highqualitybicubic;
222             g.compositingquality = compositingquality.highquality;
223 
224             int intwidth = math.min(this.size.width, this.size.height);
225             //底圆
226             g.fillellipse(new solidbrush(m_backellipsecolor), new rectangle(new point(0, 0), new size(intwidth, intwidth)));
227             if (m_showtype == hzh_controls.controls.showtype.ring)
228             {
229                 //中心圆
230                 int intcore = intwidth - m_valuewidth * 2;
231                 g.fillellipse(new solidbrush(m_coreellipsecolor), new rectangle(new point(m_valuewidth, m_valuewidth), new size(intcore, intcore)));
232                 //中心圆边框
233                 if (m_isshowcoreellipseborder)
234                 {
235                     g.drawellipse(new pen(m_valuecolor, 2), new rectangle(new point(m_valuewidth + 1, m_valuewidth + 1), new size(intcore - 1, intcore - 1)));
236                 }
237                 if (m_value > 0 && m_maxvalue > 0)
238                 {
239                     float fltpercent = (float)m_value / (float)m_maxvalue;
240                     if (fltpercent > 1)
241                     {
242                         fltpercent = 1;
243                     }
244 
245                     g.drawarc(new pen(m_valuecolor, m_valuewidth - m_valuemargin * 2), new rectanglef(new point(m_valuewidth / 2 + m_valuemargin / 4, m_valuewidth / 2 + m_valuemargin / 4), new sizef(intwidth - m_valuewidth - m_valuemargin / 2 + (m_valuemargin == 0 ? 0 : 1), intwidth - m_valuewidth - m_valuemargin / 2 + (m_valuemargin == 0 ? 0 : 1))), -90, fltpercent * 360);
246 
247                     string strvaluetext = m_valuetype == hzh_controls.controls.valuetype.percent ? fltpercent.tostring("0%") : m_value.tostring();
248                     system.drawing.sizef _txtsize = g.measurestring(strvaluetext, this.font);
249                     g.drawstring(strvaluetext, this.font, new solidbrush(this.forecolor), new pointf((intwidth - _txtsize.width) / 2 + 1, (intwidth - _txtsize.height) / 2 + 1));
250                 }
251             }
252             else
253             {
254                 if (m_value > 0 && m_maxvalue > 0)
255                 {
256                     float fltpercent = (float)m_value / (float)m_maxvalue;
257                     if (fltpercent > 1)
258                     {
259                         fltpercent = 1;
260                     }
261 
262                     g.fillpie(new solidbrush(m_valuecolor), new rectangle(m_valuemargin, m_valuemargin, intwidth - m_valuemargin * 2, intwidth - m_valuemargin * 2), -90, fltpercent * 360);
263 
264                     string strvaluetext = m_valuetype == hzh_controls.controls.valuetype.percent ? fltpercent.tostring("0%") : m_value.tostring();
265                     system.drawing.sizef _txtsize = g.measurestring(strvaluetext, this.font);
266                     g.drawstring(strvaluetext, this.font, new solidbrush(this.forecolor), new pointf((intwidth - _txtsize.width) / 2 + 1, (intwidth - _txtsize.height) / 2 + 1));
267                 }
268             }
269 
270         }
271     }
272 
273     public enum valuetype
274     {
275         /// <summary>
276         /// 百分比
277         /// </summary>
278         percent,
279         /// <summary>
280         /// 数值
281         /// </summary>
282         absolute
283     }
284 
285     public enum showtype
286     {
287         /// <summary>
288         /// 圆环
289         /// </summary>
290         ring,
291         /// <summary>
292         /// 扇形
293         /// </summary>
294         sector
295     }
296 }
 1 namespace hzh_controls.controls
 2 {
 3     partial class ucprocessellipse
 4     {
 5         /// <summary> 
 6         /// 必需的设计器变量。
 7         /// </summary>
 8         private system.componentmodel.icontainer components = null;
 9 
10         /// <summary> 
11         /// 清理所有正在使用的资源。
12         /// </summary>
13         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
14         protected override void dispose(bool disposing)
15         {
16             if (disposing && (components != null))
17             {
18                 components.dispose();
19             }
20             base.dispose(disposing);
21         }
22 
23         #region 组件设计器生成的代码
24 
25         /// <summary> 
26         /// 设计器支持所需的方法 - 不要
27         /// 使用代码编辑器修改此方法的内容。
28         /// </summary>
29         private void initializecomponent()
30         {
31             components = new system.componentmodel.container();
32             this.autoscalemode = system.windows.forms.autoscalemode.font;
33         }
34 
35         #endregion
36     }
37 }

用处及效果

最后的话

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

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

相关文章:

验证码:
移动技术网