(七十)c#Winform自定義控制項-餅狀圖

来源:https://www.cnblogs.com/bfyx/archive/2019/09/23/11572058.html
-Advertisement-
Play Games

前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_contr ...


前提

入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。

GitHub:https://github.com/kwwwvagaa/NetWinformControl

碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果覺得寫的還行,請點個 star 支持一下吧

歡迎前來交流探討: 企鵝群568015492 企鵝群568015492

麻煩博客下方點個【推薦】,謝謝

NuGet

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:[email protected]
  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 UC

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  •   為了讓我們第一時間知道程式的運行狀態,Asp.Net Core 添加了預設的日誌輸出服務。這看起來並沒有什麼問題,對於開發人員也相當友好,但如果不瞭解日誌輸出的細節,也有可能因為錯誤的日誌級別配置導致性能問題,筆者的同事在一次進行性能測試的時候被輸出日誌誤導,與其討論分析了測 ...
  • 場景 Winform中實現讀取xml配置文件並動態配置ZedGraph的RadioGroup的選項: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100540708 在上面實現了將RadioGroup的選項根據配置文件動態配置後 ...
  • 今天,他來了(weboffice線上編輯文檔)。 上次寫了一個線上預覽的博,當然,效果並不是太理想,但是緊急解決了當時的問題。 後來,小編重新查找資料,求助大牛,終於使用新的方式替換了之前的low方法。 有兩種比較好的方法,一種是webOffice,一種是pageoffice,前者免費,後者付費。果 ...
  • RSA生成公鑰和私鑰對 1 /// <summary> 2 /// RSA生成公鑰和私鑰 3 /// </summary> 4 /// <returns></returns> 5 public static string[] GenerateKeys() 6 { 7 try 8 { 9 string ...
  • 通過上一篇(abp(net core)+easyui+efcore實現倉儲管理系統——EasyUI前端頁面框架 (十八) )文章,我們已經將EasyUI添加到我們的項目中了。下麵我們通過EasyUI做為前端頁面的UI控制項來展現一個貨物信息管理的前端功能,並使用創建相應的實體類,服務類等來實現後臺功能... ...
  • 原文地址: https://blog.csdn.net/chadcao/article/details/7859394 ASP.NET的安全認證,共有“Windows”、“Form”、“Passport”、“None”四種驗證模式。下麵來說說From認證,內容分三部分: 第一部分—— 怎樣實現Fro ...
  • 場景 Winform中實現讀取xml配置文件並動態配置ZedGraph的RadioGroup的選項: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100540708 在上面實現了將RadioGroup的選項根據配置文件動態配置後 ...
  • 期待已久的.NET Core 3.0即將發佈! .NET Core 3.0在.NET Conf上發佈。大約還有9個多小時後,.NET Conf開始啟動。 為期3天的大概日程安排如下: 第1天-9月23日 9:00-10:00 Microsoft Studios播出的主題演講10:00-17:00從M ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...