入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
Install-Package HZH_Controls
https://www.cnblogs.com/bfyx/p/11364884.html
使用GDI+画的控件,不了解可以先百度下
添加一个类UCPieChart ,继承UserControl
添加一些属性
1 /// <summary>
2 /// The pie items
3 /// </summary>
4 private PieItem[] pieItems = new PieItem[0];
5
6 /// <summary>
7 /// The random
8 /// </summary>
9 private Random random = null;
10
11 /// <summary>
12 /// The format center
13 /// </summary>
14 private StringFormat formatCenter = null;
15
16 /// <summary>
17 /// The margin
18 /// </summary>
19 private int margin = 50;
20
21 /// <summary>
22 /// The m is render percent
23 /// </summary>
24 private bool m_IsRenderPercent = false;
25
26 /// <summary>
27 /// The percen format
28 /// </summary>
29 private string percenFormat = "{0:F2}%";
30
31 /// <summary>
32 /// The components
33 /// </summary>
34 private IContainer components = null;
35
36 /// <summary>
37 /// Gets or sets a value indicating whether this instance is render percent.
38 /// </summary>
39 /// <value><c>true</c> if this instance is render percent; otherwise, <c>false</c>.</value>
40 [Browsable(true)]
41 [Category("自定义")]
42 [DefaultValue(false)]
43 [Description("获取或设置是否显示百分比占用")]
44 public bool IsRenderPercent
45 {
46 get
47 {
48 return m_IsRenderPercent;
49 }
50 set
51 {
52 m_IsRenderPercent = value;
53 Invalidate();
54 }
55 }
56
57
58 /// <summary>
59 /// Gets or sets the text margin.
60 /// </summary>
61 /// <value>The text margin.</value>
62 [Browsable(true)]
63 [Category("自定义")]
64 [Description("获取或设置文本距离,单位为像素,默认50")]
65 [DefaultValue(50)]
66 public int TextMargin
67 {
68 get
69 {
70 return margin;
71 }
72 set
73 {
74 margin = value;
75 Invalidate();
76 }
77 }
78
79
80 /// <summary>
81 /// Gets or sets the percent format.
82 /// </summary>
83 /// <value>The percent format.</value>
84 [Browsable(true)]
85 [Category("自定义")]
86 [Description("获取或设置文百分比文字的格式化信息")]
87 [DefaultValue("{0:F2}%")]
88 public string PercentFormat
89 {
90 get
91 {
92 return percenFormat;
93 }
94 set
95 {
96 percenFormat = value;
97 Invalidate();
98 }
99 }
100
101 /// <summary>
102 /// The center of circle color
103 /// </summary>
104 private Color centerOfCircleColor = Color.White;
105 /// <summary>
106 /// Gets or sets the color of the center of circle.
107 /// </summary>
108 /// <value>The color of the center of circle.</value>
109 [Browsable(true)]
110 [Category("自定义")]
111 [Description("获取或设置圆心颜色")]
112 public Color CenterOfCircleColor
113 {
114 get { return centerOfCircleColor; }
115 set
116 {
117 centerOfCircleColor = value;
118 Invalidate();
119 }
120 }
121
122 /// <summary>
123 /// The center of circle width
124 /// </summary>
125 private int centerOfCircleWidth = 0;
126 /// <summary>
127 /// Gets or sets the width of the center of circle.
128 /// </summary>
129 /// <value>The width of the center of circle.</value>
130 [Browsable(true)]
131 [Category("自定义")]
132 [Description("获取或设置圆心宽度")]
133 public int CenterOfCircleWidth
134 {
135 get { return centerOfCircleWidth; }
136 set
137 {
138 if (value < 0)
139 return;
140 centerOfCircleWidth = value;
141 Invalidate();
142 }
143 }
144
145 /// <summary>
146 /// The title
147 /// </summary>
148 private string title;
149 /// <summary>
150 /// Gets or sets the ti tle.
151 /// </summary>
152 /// <value>The ti tle.</value>
153 [Browsable(true)]
154 [Category("自定义")]
155 [Description("获取或设置标题")]
156 public string TiTle
157 {
158 get { return title; }
159 set
160 {
161 title = value;
162 ResetTitleHeight();
163 Invalidate();
164 }
165 }
166 /// <summary>
167 /// The title font
168 /// </summary>
169 private Font titleFont = new Font("微软雅黑", 12);
170 /// <summary>
171 /// Gets or sets the title font.
172 /// </summary>
173 /// <value>The title font.</value>
174 [Browsable(true)]
175 [Category("自定义")]
176 [Description("获取或设置标题字体")]
177 public Font TitleFont
178 {
179 get { return titleFont; }
180 set
181 {
182 titleFont = value;
183 ResetTitleHeight();
184 Invalidate();
185 }
186 }
187
188 /// <summary>
189 /// The title froe color
190 /// </summary>
191 private Color titleFroeColor = Color.Black;
192 /// <summary>
193 /// Gets or sets the color of the title froe.
194 /// </summary>
195 /// <value>The color of the title froe.</value>
196 [Browsable(true)]
197 [Category("自定义")]
198 [Description("获取或设置标题颜色")]
199 public Color TitleFroeColor
200 {
201 get { return titleFroeColor; }
202 set
203 {
204 titleFroeColor = value;
205 Invalidate();
206 }
207 }
208
209 /// <summary>
210 /// The title size
211 /// </summary>
212 private SizeF titleSize = SizeF.Empty;
213 /// <summary>
214 /// Resets the height of the title.
215 /// </summary>
216 private void ResetTitleHeight()
217 {
218 if (string.IsNullOrEmpty(title))
219 titleSize = SizeF.Empty;
220 else
221 {
222 using (var g = this.CreateGraphics())
223 {
224 titleSize = g.MeasureString(title, titleFont);
225 }
226 }
227 }
228
229 /// <summary>
230 /// Gets or sets the data source.
231 /// </summary>
232 /// <value>The data source.</value>
233 [Browsable(true)]
234 [Category("自定义")]
235 [Description("获取或设置标题颜色")]
236 [Localizable(true)]
237 public PieItem[] DataSource
238 {
239 get { return pieItems; }
240 set
241 {
242 pieItems = value;
243 Invalidate();
244 }
245 }
重绘
1 protected override void OnPaint(PaintEventArgs e)
2 {
3 e.Graphics.SetGDIHigh();
4
5 int width;
6 Point centerPoint = GetCenterPoint(out width);
7 Rectangle rectangle = new Rectangle(centerPoint.X - width, centerPoint.Y - width, width * 2, width * 2);
8 if (width > 0 && pieItems.Length != 0)
9 {
10 if (!string.IsNullOrEmpty(title))
11 e.Graphics.DrawString(title, titleFont, new SolidBrush(titleFroeColor), new PointF((this.Width - titleSize.Width) / 2, 5));
12 Rectangle rect = new Rectangle(rectangle.X - centerPoint.X, rectangle.Y - centerPoint.Y, rectangle.Width, rectangle.Height);
13 e.Graphics.TranslateTransform(centerPoint.X, centerPoint.Y);
14 e.Graphics.RotateTransform(90f);
15 int num = pieItems.Sum((PieItem item) => item.Value);
16 float num2 = 0f;
17 float num3 = -90f;
18 for (int i = 0; i < pieItems.Length; i++)
19 {
20 Color cItem = pieItems[i].PieColor ?? ControlHelper.Colors[i];
21 Pen pen = new Pen(cItem, 1f);
22 SolidBrush solidBrush = new SolidBrush(cItem);
23 SolidBrush solidBrush2 = new SolidBrush(cItem);
24 Brush percentBrush = new SolidBrush(cItem);
25 float num4 = e.Graphics.MeasureString(pieItems[i].Name, Font).Width + 3f;
26 float num5 = (num != 0) ? Convert.ToSingle((double)pieItems[i].Value * 1.0 / (double)num * 360.0) : ((float)(360 / pieItems.Length));
27 e.Graphics.FillPie(solidBrush, rect, 0f, 0f - num5);
28 e.Graphics.DrawPie(new Pen(solidBrush), rect, 0f, 0f - num5);
29 e.Graphics.RotateTransform(0f - num5 / 2f);
30 if (num5 < 2f)
31 {
32 num2 += num5;
33 }
34 else
35 {
36 num2 += num5 / 2f;
37 int num6 = 15;
38 if (num2 < 45f || num2 > 315f)
39 {
40 num6 = 20;
41 }
42 if (num2 > 135f && num2 < 225f)
43 {
44 num6 = 20;
45 }
46 e.Graphics.DrawLine(pen, width * 2 / 3, 0, width + num6, 0);
47 e.Graphics.TranslateTransform(width + num6, 0f);
48 if (num2 - num3 < 5f)
49 {
50 }
51 num3 = num2;
52 if (num2 < 180f)
53 {
54 e.Graphics.RotateTransform(num2 - 90f);
55 e.Graphics.DrawLine(pen, 0f, 0f, num4, 0f);
56 e.Graphics.DrawString(pieItems[i].Name, Font, solidBrush2, new Point(0, -Font.Height));
57 if (IsRenderPercent)
58 {
59 e.Graphics.DrawString(string.Format(percenFormat, num5 * 100f / 360f), Font, percentBrush, new Point(0, 1));
60 }
61 e.Graphics.RotateTransform(90f - num2);
62 }
63 else
64 {
65 e.Graphics.RotateTransform(num2 - 270f);
66 e.Graphics.DrawLine(pen, 0f, 0f, num4, 0f);
67 e.Graphics.TranslateTransform(num4 - 3f, 0f);
68 e.Graphics.RotateTransform(180f);
69 e.Graphics.DrawString(pieItems[i].Name, Font, solidBrush2, new Point(0, -Font.Height));
70 if (IsRenderPercent)
71 {
72 e.Graphics.DrawString(string.Format(percenFormat, num5 * 100f / 360f), Font, percentBrush, new Point(0, 1));
73 }
74 e.Graphics.RotateTransform(-180f);
75 e.Graphics.TranslateTransform(0f - num4 + 3f, 0f);
76 e.Graphics.RotateTransform(270f - num2);
77 }
78 e.Graphics.TranslateTransform(-width - num6, 0f);
79 e.Graphics.RotateTransform(0f - num5 / 2f);
80 num2 += num5 / 2f;
81 }
82 solidBrush.Dispose();
83 pen.Dispose();
84 solidBrush2.Dispose();
85 percentBrush.Dispose();
86 }
87 e.Graphics.ResetTransform();
88
89 if (centerOfCircleWidth > 0)
90 {
91 Rectangle rectCenter = new Rectangle(rect.Left + rect.Width / 2 - centerOfCircleWidth / 2, rect.Top + rect.Height / 2 - centerOfCircleWidth / 2, centerOfCircleWidth, centerOfCircleWidth);
92 e.Graphics.FillEllipse(new SolidBrush(centerOfCircleColor), rectCenter);
93 }
94 }
95 else
96 {
97 e.Graphics.FillEllipse(Brushes.AliceBlue, rectangle);
98 e.Graphics.DrawEllipse(Pens.DodgerBlue, rectangle);
99 e.Graphics.DrawString("无数据", Font, Brushes.DimGray, rectangle, formatCenter);
100 }
101 base.OnPaint(e);
102 }
一些辅助函数
1 /// <summary>
2 /// Sets the data source.
3 /// </summary>
4 /// <param name="source">The source.</param>
5 public void SetDataSource(PieItem[] source)
6 {
7 if (source != null)
8 {
9 DataSource = source;
10 }
11 }
12 /// <summary>
13 /// Sets the data source.
14 /// </summary>
15 /// <param name="names">The names.</param>
16 /// <param name="values">The values.</param>
17 /// <exception cref="System.ArgumentNullException">
18 /// names
19 /// or
20 /// values
21 /// </exception>
22 /// <exception cref="System.Exception">两个数组的长度不一致!</exception>
23 public void SetDataSource(string[] names, int[] values)
24 {
25 if (names == null)
26 {
27 throw new ArgumentNullException("names");
28 }
29 if (values == null)
30 {
31 throw new ArgumentNullException("values");
32 }
33 if (names.Length != values.Length)
34 {
35 throw new Exception("两个数组的长度不一致!");
36 }
37 pieItems = new PieItem[names.Length];
38 for (int i = 0; i < names.Length; i++)
39 {
40 pieItems[i] = new PieItem
41 {
42 Name = names[i],
43 Value = values[i]
44 };
45 }
46 Invalidate();
47 }
完整代码
1 // ***********************************************************************
2 // Assembly : HZH_Controls
3 // Created : 2019-09-23
4 //
5 // ***********************************************************************
6 // <copyright file="UCPieChart.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.ComponentModel;
18 using System.ComponentModel.Design;
19 using System.Drawing;
20 using System.Drawing.Drawing2D;
21 using System.Drawing.Text;
22 using System.Linq;
23 using System.Windows.Forms;
24
25 namespace HZH_Controls.Controls
26 {
27 /// <summary>
28 /// Class UCPieChart.
29 /// Implements the <see cref="System.Windows.Forms.UserControl" />
30 /// </summary>
31 /// <seealso cref="System.Windows.Forms.UserControl" />
32 public class UCPieChart : UserControl
33 {
34 /// <summary>
35 /// The pie items
36 /// </summary>
37 private PieItem[] pieItems = new PieItem[0];
38
39 /// <summary>
40 /// The random
41 /// </summary>
42 private Random random = null;
43
44 /// <summary>
45 /// The format center
46 /// </summary>
47 private StringFormat formatCenter = null;
48
49 /// <summary>
50 /// The margin
51 /// </summary>
52 private int margin = 50;
53
54 /// <summary>
55 /// The m is render percent
56 /// </summary>
57 private bool m_IsRenderPercent = false;
58
59 /// <summary>
60 /// The percen format
61 /// </summary>
62 private string percenFormat = "{0:F2}%";
63
64 /// <summary>
65 /// The components
66 /// </summary>
67 private IContainer components = null;
68
69 /// <summary>
70 /// Gets or sets a value indicating whether this instance is render percent.
71 /// </summary>
72 /// <value><c>true</c> if this instance is render percent; otherwise, <c>false</c>.</value>
73 [Browsable(true)]
74 [Category("自定义")]
75 [DefaultValue(false)]
76 [Description("获取或设置是否显示百分比占用")]
77 public bool IsRenderPercent
78 {
79 get
80 {
81 return m_IsRenderPercent;
82 }
83 set
84 {
85 m_IsRenderPercent = value;
86 Invalidate();
87 }
88 }
89
90
91 /// <summary>
92 /// Gets or sets the text margin.
93 /// </summary>
94 /// <value>The text margin.</value>
95 [Browsable(true)]
96 [Category("自定义")]
97 [Description("获取或设置文本距离,单位为像素,默认50")]
98 [DefaultValue(50)]
99 public int TextMargin
100 {
101 get
102 {
103 return margin;
104 }
105 set
106 {
107 margin = value;
108 Invalidate();
109 }
110 }
111
112
113 /// <summary>
114 /// Gets or sets the percent format.
115 /// </summary>
116 /// <value>The percent format.</value>
117 [Browsable(true)]
118 [Category("自定义")]
119 [Description("获取或设置文百分比文字的格式化信息")]
120 [DefaultValue("{0:F2}%")]
121 public string PercentFormat
122 {
123 get
124 {
125 return percenFormat;
126 }
127 set
128 {
129 percenFormat = value;
130 Invalidate();
131 }
132 }
133
134 /// <summary>
135 /// The center of circle color
136 /// </summary>
137 private Color centerOfCircleColor = Color.White;
138 /// <summary>
139 /// Gets or sets the color of the center of circle.
140 /// </summary>
141 /// <value>The color of the center of circle.</value>
142 [Browsable(true)]
143 [Category("自定义")]
144 [Description("获取或设置圆心颜色")]
145 public Color CenterOfCircleColor
146 {
147 get { return centerOfCircleColor; }
148 set
149 {
150 centerOfCircleColor = value;
151 Invalidate();
152 }
153 }
154
155 /// <summary>
156 /// The center of circle width
157 /// </summary>
158 private int centerOfCircleWidth = 0;
159 /// <summary>
160 /// Gets or sets the width of the center of circle.
161 /// </summary>
162 /// <value>The width of the center of circle.</value>
163 [Browsable(true)]
164 [Category("自定义")]
165 [Description("获取或设置圆心宽度")]
166 public int CenterOfCircleWidth
167 {
168 get { return centerOfCircleWidth; }
169 set
170 {
171 if (value < 0)
172 return;
173 centerOfCircleWidth = value;
174 Invalidate();
175 }
176 }
177
178 /// <summary>
179 /// The title
180 /// </summary>
181 private string title;
182 /// <summary>
183 /// Gets or sets the ti tle.
184 /// </summary>
185 /// <value>The ti tle.</value>
186 [Browsable(true)]
187 [Category("自定义")]
188 [Description("获取或设置标题")]
189 public string TiTle
190 {
191 get { return title; }
192 set
193 {
194 title = value;
195 ResetTitleHeight();
196 Invalidate();
197 }
198 }
199 /// <summary>
200 /// The title font
201 /// </summary>
202 private Font titleFont = new Font("微软雅黑", 12);
203 /// <summary>
204 /// Gets or sets the title font.
205 /// </summary>
206 /// <value>The title font.</value>
207 [Browsable(true)]
208 [Category("自定义")]
209 [Description("获取或设置标题字体")]
210 public Font TitleFont
211 {
212 get { return titleFont; }
213 set
214 {
215 titleFont = value;
216 ResetTitleHeight();
217 Invalidate();
218 }
219 }
220
221 /// <summary>
222 /// The title froe color
223 /// </summary>
224 private Color titleFroeColor = Color.Black;
225 /// <summary>
226 /// Gets or sets the color of the title froe.
227 /// </summary>
228 /// <value>The color of the title froe.</value>
229 [Browsable(true)]
230 [Category("自定义")]
231 [Description("获取或设置标题颜色")]
232 public Color TitleFroeColor
233 {
234 get { return titleFroeColor; }
235 set
236 {
237 titleFroeColor = value;
238 Invalidate();
239 }
240 }
241
242 /// <summary>
243 /// The title size
244 /// </summary>
245 private SizeF titleSize = SizeF.Empty;
246 /// <summary>
247 /// Resets the height of the title.
248 /// </summary>
249 private void ResetTitleHeight()
250 {
251 if (string.IsNullOrEmpty(title))
252 titleSize = SizeF.Empty;
253 else
254 {
255 using (var g = this.CreateGraphics())
256 {
257 titleSize = g.MeasureString(title, titleFont);
258 }
259 }
260 }
261
262 /// <summary>
263 /// Gets or sets the data source.
264 /// </summary>
265 /// <value>The data source.</value>
266 [Browsable(true)]
267 [Category("自定义")]
268 [Description("获取或设置标题颜色")]
269 [Localizable(true)]
270 public PieItem[] DataSource
271 {
272 get { return pieItems; }
273 set
274 {
275 pieItems = value;
276 Invalidate();
277 }
278 }
279
280 /// <summary>
281 /// Initializes a new instance of the <see cref="UCPieChart"/> class.
282 /// </summary>
283 public UCPieChart()
284 {
285 InitializeComponent();
286 random = new Random();
287 formatCenter = new StringFormat();
288 formatCenter.Alignment = StringAlignment.Center;
289 formatCenter.LineAlignment = StringAlignment.Center;
290 SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true);
291 SetStyle(ControlStyles.ResizeRedraw, true);
292 SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
293 SetStyle(ControlStyles.AllPaintingInWmPaint, true);
294 pieItems = new PieItem[0];
295 if (GetService(typeof(IDesignerHost)) != null || LicenseManager.UsageMode == LicenseUsageMode.Designtime)
296 {
297 pieItems = new PieItem[5];
298
299 for (int i = 0; i < 5; i++)
300 {
301 pieItems[i] = new PieItem
302 {
303 Name = "Source" + (i + 1),
304 Value = random.Next(10, 100)
305 };
306 }
307 }
308 }
309
310
311
312 /// <summary>
313 /// Gets the center point.
314 /// </summary>
315 /// <param name="width">The width.</param>
316 /// <returns>Point.</returns>
317 private Point GetCenterPoint(out int width)
318 {
319 width = Math.Min(base.Width, base.Height - (titleSize != SizeF.Empty ? ((int)titleSize.Height) : 0)) / 2 - margin - 8;
320 return new Point(base.Width / 2 - 1, base.Height / 2 + (titleSize != SizeF.Empty ? ((int)titleSize.Height) : 0) - 1);
321 }
322
323
324 /// <summary>
325 /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
326 /// </summary>
327 /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
328 protected override void OnPaint(PaintEventArgs e)
329 {
330 e.Graphics.SetGDIHigh();
331
332 int width;
333 Point centerPoint = GetCenterPoint(out width);
334 Rectangle rectangle = new Rectangle(centerPoint.X - width, centerPoint.Y - width, width * 2, width * 2);
335 if (width > 0 && pieItems.Length != 0)
336 {
337 if (!string.IsNullOrEmpty(title))
338 e.Graphics.DrawString(title, titleFont, new SolidBrush(titleFroeColor), new PointF((this.Width - titleSize.Width) / 2, 5));
339 Rectangle rect = new Rectangle(rectangle.X - centerPoint.X, rectangle.Y - centerPoint.Y, rectangle.Width, rectangle.Height);
340 e.Graphics.TranslateTransform(centerPoint.X, centerPoint.Y);
341 e.Graphics.RotateTransform(90f);
342 int num = pieItems.Sum((PieItem item) => item.Value);
343 float num2 = 0f;
344 float num3 = -90f;
345 for (int i = 0; i < pieItems.Length; i++)
346 {
347 Color cItem = pieItems[i].PieColor ?? ControlHelper.Colors[i];
348 Pen pen = new Pen(cItem, 1f);
349 SolidBrush solidBrush = new SolidBrush(cItem);
350 SolidBrush solidBrush2 = new SolidBrush(cItem);
351 Brush percentBrush = new SolidBrush(cItem);
352 float num4 = e.Graphics.MeasureString(pieItems[i].Name, Font).Width + 3f;
353 float num5 = (num != 0) ? Convert.ToSingle((double)pieItems[i].Value * 1.0 / (double)num * 360.0) : ((float)(360 / pieItems.Length));
354 e.Graphics.FillPie(solidBrush, rect, 0f, 0f - num5);
355 e.Graphics.DrawPie(new Pen(solidBrush), rect, 0f, 0f - num5);
356 e.Graphics.RotateTransform(0f - num5 / 2f);
357 if (num5 < 2f)
358 {
359 num2 += num5;
360 }
361 else
362 {
363 num2 += num5 / 2f;
364 int num6 = 15;
365 if (num2 < 45f || num2 > 315f)
366 {
367 num6 = 20;
368 }
369 if (num2 > 135f && num2 < 225f)
370 {
371 num6 = 20;
372 }
373 e.Graphics.DrawLine(pen, width * 2 / 3, 0, width + num6, 0);
374 e.Graphics.TranslateTransform(width + num6, 0f);
375 if (num2 - num3 < 5f)
376 {
377 }
378 num3 = num2;
379 if (num2 < 180f)
380 {
381 e.Graphics.RotateTransform(num2 - 90f);
382 e.Graphics.DrawLine(pen, 0f, 0f, num4, 0f);
383 e.Graphics.DrawString(pieItems[i].Name, Font, solidBrush2, new Point(0, -Font.Height));
384 if (IsRenderPercent)
385 {
386 e.Graphics.DrawString(string.Format(percenFormat, num5 * 100f / 360f), Font, percentBrush, new Point(0, 1));
387 }
388 e.Graphics.RotateTransform(90f - num2);
389 }
390 else
391 {
392 e.Graphics.RotateTransform(num2 - 270f);
393 e.Graphics.DrawLine(pen, 0f, 0f, num4, 0f);
394 e.Graphics.TranslateTransform(num4 - 3f, 0f);
395 e.Graphics.RotateTransform(180f);
396 e.Graphics.DrawString(pieItems[i].Name, Font, solidBrush2, new Point(0, -Font.Height));
397 if (IsRenderPercent)
398 {
399 e.Graphics.DrawString(string.Format(percenFormat, num5 * 100f / 360f), Font, percentBrush, new Point(0, 1));
400 }
401 e.Graphics.RotateTransform(-180f);
402 e.Graphics.TranslateTransform(0f - num4 + 3f, 0f);
403 e.Graphics.RotateTransform(270f - num2);
404 }
405 e.Graphics.TranslateTransform(-width - num6, 0f);
406 e.Graphics.RotateTransform(0f - num5 / 2f);
407 num2 += num5 / 2f;
408 }
409 solidBrush.Dispose();
410 pen.Dispose();
411 solidBrush2.Dispose();
412 percentBrush.Dispose();
413 }
414 e.Graphics.ResetTransform();
415
416 if (centerOfCircleWidth > 0)
417 {
418 Rectangle rectCenter = new Rectangle(rect.Left + rect.Width / 2 - centerOfCircleWidth / 2, rect.Top + rect.Height / 2 - centerOfCircleWidth / 2, centerOfCircleWidth, centerOfCircleWidth);
419 e.Graphics.FillEllipse(new SolidBrush(centerOfCircleColor), rectCenter);
420 }
421 }
422 else
423 {
424 e.Graphics.FillEllipse(Brushes.AliceBlue, rectangle);
425 e.Graphics.DrawEllipse(Pens.DodgerBlue, rectangle);
426 e.Graphics.DrawString("无数据", Font, Brushes.DimGray, rectangle, formatCenter);
427 }
428 base.OnPaint(e);
429 }
430 /// <summary>
431 /// Sets the data source.
432 /// </summary>
433 /// <param name="source">The source.</param>
434 public void SetDataSource(PieItem[] source)
435 {
436 if (source != null)
437 {
438 DataSource = source;
439 }
440 }
441 /// <summary>
442 /// Sets the data source.
443 /// </summary>
444 /// <param name="names">The names.</param>
445 /// <param name="values">The values.</param>
446 /// <exception cref="System.ArgumentNullException">
447 /// names
448 /// or
449 /// values
450 /// </exception>
451 /// <exception cref="System.Exception">两个数组的长度不一致!</exception>
452 public void SetDataSource(string[] names, int[] values)
453 {
454 if (names == null)
455 {
456 throw new ArgumentNullException("names");
457 }
458 if (values == null)
459 {
460 throw new ArgumentNullException("values");
461 }
462 if (names.Length != values.Length)
463 {
464 throw new Exception("两个数组的长度不一致!");
465 }
466 pieItems = new PieItem[names.Length];
467 for (int i = 0; i < names.Length; i++)
468 {
469 pieItems[i] = new PieItem
470 {
471 Name = names[i],
472 Value = values[i]
473 };
474 }
475 Invalidate();
476 }
477
478 /// <summary>
479 /// Releases unmanaged and - optionally - managed resources.
480 /// </summary>
481 /// <param name="disposing">为 true 则释放托管资源和非托管资源;为 false 则仅释放非托管资源。</param>
482 protected override void Dispose(bool disposing)
483 {
484 if (disposing && components != null)
485 {
486 components.Dispose();
487 }
488 base.Dispose(disposing);
489 }
490
491 /// <summary>
492 /// Initializes the component.
493 /// </summary>
494 private void InitializeComponent()
495 {
496 SuspendLayout();
497 base.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
498 BackColor = System.Drawing.Color.Transparent;
499 base.Name = "UCPieChart";
500 ResumeLayout(false);
501 }
502 }
503 }