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

Posted bfyx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(三十八)c#Winform自定义控件-圆形进度条相关的知识,希望对你有一定的参考价值。

前提

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

开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control

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

欢迎前来交流探讨: 企鹅群568015492 技术图片

目录

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

准备工作

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

开始

添加一个用户控件,命名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 
View Code
技术图片
 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 
View Code

用处及效果

技术图片

技术图片

最后的话

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

以上是关于(三十八)c#Winform自定义控件-圆形进度条的主要内容,如果未能解决你的问题,请参考以下文章

(四十六)c#Winform自定义控件-水波进度条

C# 自定义控件(圆形进度条) Xamarin Forms

Android自定义控件篇 圆形进度条

Android自定义控件篇 圆形进度条

Android 圆形进度条控件

自定义控件——圆形圆点进度条(仿安全卫士中的一键加速)