标签:tor 思路 图片 ide 内容 ace ase white 重绘
前提
入行已经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 ///
4 /// 百分比
5 ///
6 Percent,
7 ///
8 /// 数值
9 ///
10 Absolute
11 }
12
13 public enum ShowType
14 {
15 ///
16 /// 圆环
17 ///
18 Ring,
19 ///
20 /// 扇形
21 ///
22 Sector
23 }
添加属性
1 [Description("值改变事件"), Category("自定义")]
2 public event EventHandler ValueChanged;
3
4 private Color m_backEllipseColor = Color.FromArgb(22, 160, 133);
5 ///
6 /// 圆背景色
7 ///
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 ///
21 /// 内圆颜色,ShowType=Ring 有效
22 ///
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 ///
49 /// 内圆是否显示边框,ShowType=Ring 有效
50 ///
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 ///
64 /// 值文字类型
65 ///
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 ///
79 /// 外圆值宽度
80 ///
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 ///
96 /// 外圆值间距
97 ///
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 ///
113 /// 最大值
114 ///
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 ///
130 /// 当前值
131 ///
132 [Description("当前值"), Category("自定义")]
133 public int Value
134 {
135 get { return m_value; }
136 set
137 {
138 if (m_maxValue 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 ///
20 /// 圆背景色
21 ///
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 ///
35 /// 内圆颜色,ShowType=Ring 有效
36 ///
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 ///
63 /// 内圆是否显示边框,ShowType=Ring 有效
64 ///
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 ///
78 /// 值文字类型
79 ///
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 ///
93 /// 外圆值宽度
94 ///
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 ///
110 /// 外圆值间距
111 ///
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 ///
127 /// 最大值
128 ///
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 ///
144 /// 当前值
145 ///
146 [Description("当前值"), Category("自定义")]
147 public int Value
148 {
149 get { return m_value; }
150 set
151 {
152 if (m_maxValue 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 ///
276