主頁 > .NET開發 > (七十二)c#Winform自定義控制元件-雷達圖-HZHControls

(七十二)c#Winform自定義控制元件-雷達圖-HZHControls

2020-09-11 17:39:47 .NET開發

官網

http://www.hzhcontrols.com

前提

入行已經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+畫的,不會的可以先百度了解下

開始

添加一個類UCRadarChart ,繼承 UserControl

添加一些控制屬性

  1  /// <summary>  2         /// The split count  3         /// </summary>  4         private int splitCount = 5;  5         /// <summary>  6         /// Gets or sets the split count.  7         /// </summary>  8         /// <value>The split count.</value>  9         [Browsable(true)] 10         [Category("自定義")] 11         [Description("獲取或設定分隔份數")] 12         public int SplitCount 13         { 14             get { return splitCount; } 15             set 16             { 17                 splitCount = value; 18                 Invalidate(); 19             } 20         } 21  22         /// <summary> 23         /// The split odd color 24         /// </summary> 25         private Color splitOddColor = Color.White; 26         /// <summary> 27         /// 分隔奇數欄背景色 28         /// </summary> 29         /// <value>The color of the split odd.</value> 30         [Browsable(true)] 31         [Category("自定義")] 32         [Description("獲取或設定分隔奇數欄背景色")] 33         public Color SplitOddColor 34         { 35             get { return splitOddColor; } 36             set 37             { 38                 splitOddColor = value; 39                 Invalidate(); 40             } 41         } 42         /// <summary> 43         /// The split even color 44         /// </summary> 45         private Color splitEvenColor = Color.FromArgb(232, 232, 232); 46         /// <summary> 47         /// 分隔偶數欄背景色 48         /// </summary> 49         /// <value>The color of the split even.</value> 50         [Browsable(true)] 51         [Category("自定義")] 52         [Description("獲取或設定分隔偶數欄背景色")] 53         public Color SplitEvenColor 54         { 55             get { return splitEvenColor; } 56             set { splitEvenColor = value; } 57         } 58  59         /// <summary> 60         /// The line color 61         /// </summary> 62         private Color lineColor = Color.FromArgb(153, 153, 153); 63         /// <summary> 64         /// Gets or sets the color of the line. 65         /// </summary> 66         /// <value>The color of the line.</value> 67         [Browsable(true)] 68         [Category("自定義")] 69         [Description("獲取或設定線條色")] 70         public Color LineColor 71         { 72             get { return lineColor; } 73             set 74             { 75                 lineColor = value; 76                 Invalidate(); 77             } 78         } 79  80         /// <summary> 81         /// The radar positions 82         /// </summary> 83         private RadarPosition[] radarPositions; 84         /// <summary> 85         /// 節點串列,至少需要3個 86         /// </summary> 87         /// <value>The radar positions.</value> 88         [Browsable(true)] 89         [Category("自定義")] 90         [Description("獲取或設定節點,至少需要3個")] 91         public RadarPosition[] RadarPositions 92         { 93             get { return radarPositions; } 94             set 95             { 96                 radarPositions = value; 97                 Invalidate(); 98             } 99         }100 101         /// <summary>102         /// The title103         /// </summary>104         private string title;105         /// <summary>106         /// 標題107         /// </summary>108         /// <value>The title.</value>109         [Browsable(true)]110         [Category("自定義")]111         [Description("獲取或設定標題")]112         public string Title113         {114             get { return title; }115             set116             {117                 title = value;118                 ResetTitleSize();119                 Invalidate();120             }121         }122 123         /// <summary>124         /// The title font125         /// </summary>126         private Font titleFont = new Font("微軟雅黑", 12);127         /// <summary>128         /// Gets or sets the title font.129         /// </summary>130         /// <value>The title font.</value>131         [Browsable(true)]132         [Category("自定義")]133         [Description("獲取或設定標題字體")]134         public Font TitleFont135         {136             get { return titleFont; }137             set138             {139                 titleFont = value;140                 ResetTitleSize();141                 Invalidate();142             }143         }144 145         /// <summary>146         /// The title color147         /// </summary>148         private Color titleColor = Color.Black;149         /// <summary>150         /// Gets or sets the color of the title.151         /// </summary>152         /// <value>The color of the title.</value>153         [Browsable(true)]154         [Category("自定義")]155         [Description("獲取或設定標題文本顏色")]156         public Color TitleColor157         {158             get { return titleColor; }159             set160             {161                 titleColor = value;162                 Invalidate();163             }164         }165 166         /// <summary>167         /// The lines168         /// </summary>169         private RadarLine[] lines;170         /// <summary>171         /// Gets or sets the lines.172         /// </summary>173         /// <value>The lines.</value>174         [Browsable(true)]175         [Category("自定義")]176         [Description("獲取或設定值線條,Values長度必須與RadarPositions長度一致,否則無法顯示")]177         public RadarLine[] Lines178         {179             get { return lines; }180             set181             {182                 lines = value;183                 Invalidate();184             }185         }186 187 188         /// <summary>189         /// The title size190         /// </summary>191         SizeF titleSize = SizeF.Empty;192         /// <summary>193         /// The m rect working194         /// </summary>195         private RectangleF m_rectWorking = Rectangle.Empty;196         /// <summary>197         /// The line value type size198         /// </summary>199         SizeF lineValueTypeSize = SizeF.Empty;200         /// <summary>201         /// The int line value COM count202         /// </summary>203         int intLineValueComCount = 0;204         /// <summary>205         /// The int line value row count206         /// </summary>207         int intLineValueRowCount = 0;

屬性改變時處理作業區域

 1  /// <summary> 2         /// Handles the SizeChanged event of the UCRadarChart control. 3         /// </summary> 4         /// <param name="sender">The source of the event.</param> 5         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param> 6         void UCRadarChart_SizeChanged(object sender, EventArgs e) 7         { 8             ResetWorkingRect(); 9         }10 11         /// <summary>12         /// Resets the working rect.13         /// </summary>14         private void ResetWorkingRect()15         {16             if (lines != null && lines.Length > 0)17             {18                 using (Graphics g = this.CreateGraphics())19                 {20                     foreach (var item in lines)21                     {22                         var s = g.MeasureString(item.Name, Font);23                         if (s.Width > lineValueTypeSize.Width)24                             lineValueTypeSize = s;25                     }26                 }27             }28             var lineTypePanelHeight = 0f;29             if (lineValueTypeSize != SizeF.Empty)30             {31                 intLineValueComCount = (int)(this.Width / (lineValueTypeSize.Width + 25));32 33                 intLineValueRowCount = lines.Length / intLineValueComCount;34                 if (lines.Length % intLineValueComCount != 0)35                 {36                     intLineValueRowCount++;37                 }38                 lineTypePanelHeight = (lineValueTypeSize.Height + 10) * intLineValueRowCount;39             }40             var min = Math.Min(this.Width, this.Height - titleSize.Height - lineTypePanelHeight);41             var rectWorking = new RectangleF((this.Width - min) / 2 + 10, titleSize.Height + lineTypePanelHeight + 10, min - 10, min - 10);42             //處理文字43             float fltSplitAngle = 360F / radarPositions.Length;44             float fltRadiusWidth = rectWorking.Width / 2;45             float minX = rectWorking.Left;46             float maxX = rectWorking.Right;47             float minY = rectWorking.Top;48             float maxY = rectWorking.Bottom;49             using (Graphics g = this.CreateGraphics())50             {51                 PointF centrePoint = new PointF(rectWorking.Left + rectWorking.Width / 2, rectWorking.Top + rectWorking.Height / 2);52                 for (int i = 0; i < radarPositions.Length; i++)53                 {54                     float fltAngle = 270 + fltSplitAngle * i;55                     fltAngle = fltAngle % 360;56                     PointF _point = GetPointByAngle(centrePoint, fltAngle, fltRadiusWidth);57                     var _txtSize = g.MeasureString(radarPositions[i].Text, Font);58                     if (_point.X < centrePoint.X)//59                     {60                         if (_point.X - _txtSize.Width < minX)61                         {62                             minX = rectWorking.Left + _txtSize.Width;63                         }64                     }65                     else//66                     {67                         if (_point.X + _txtSize.Width > maxX)68                         {69                             maxX = rectWorking.Right - _txtSize.Width;70                         }71                     }72                     if (_point.Y < centrePoint.Y)//73                     {74                         if (_point.Y - _txtSize.Height < minY)75                         {76                             minY = rectWorking.Top + _txtSize.Height;77                         }78                     }79                     else//80                     {81                         if (_point.Y + _txtSize.Height > maxY)82                         {83                             maxY = rectWorking.Bottom - _txtSize.Height;84                         }85                     }86                 }87             }88 89             min = Math.Min(maxX - minX, maxY - minY);90             m_rectWorking = new RectangleF(minX, minY, min, min);91         }

重繪

  1 protected override void OnPaint(PaintEventArgs e)  2         {  3             base.OnPaint(e);  4             var g = e.Graphics;  5             g.SetGDIHigh();  6   7             if (!string.IsNullOrEmpty(title))  8             {  9                 g.DrawString(title, titleFont, new SolidBrush(titleColor), new RectangleF(m_rectWorking.Left + (m_rectWorking.Width - titleSize.Width) / 2, m_rectWorking.Top - titleSize.Height - 10 - (intLineValueRowCount * (10 + lineValueTypeSize.Height)), titleSize.Width, titleSize.Height)); 10             } 11  12             if (radarPositions.Length <= 2) 13             { 14                 g.DrawString("至少需要3個頂點", Font, new SolidBrush(Color.Black), m_rectWorking, new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }); 15                 return; 16             } 17  18             var y = m_rectWorking.Top - 20 - (intLineValueRowCount * (10 + lineValueTypeSize.Height)); 19  20             for (int i = 0; i < intLineValueRowCount; i++) 21             { 22                 var x = 0f; 23                 int intCount = intLineValueComCount; 24                 if (i == intLineValueRowCount - 1) 25                 { 26                     intCount = lines.Length % intLineValueComCount; 27  28                 } 29                 x = m_rectWorking.Left + (m_rectWorking.Width - intCount * (lineValueTypeSize.Width + 25)) / 2; 30  31                 for (int j = 0; j < intCount; j++) 32                 { 33                     g.FillRectangle(new SolidBrush(lines[i * intLineValueComCount + j].LineColor.Value), new RectangleF(x + (lineValueTypeSize.Width + 25)*j, y + lineValueTypeSize.Height * i, 15, lineValueTypeSize.Height)); 34                     g.DrawString(lines[i * intLineValueComCount + j].Name, Font, new SolidBrush(lines[i * intLineValueComCount + j].LineColor.Value), new PointF(x + (lineValueTypeSize.Width + 25) * j + 20, y + lineValueTypeSize.Height * i)); 35                 } 36             } 37  38             float fltSplitAngle = 360F / radarPositions.Length; 39             float fltRadiusWidth = m_rectWorking.Width / 2; 40             float fltSplitRadiusWidth = fltRadiusWidth / splitCount; 41             PointF centrePoint = new PointF(m_rectWorking.Left + m_rectWorking.Width / 2, m_rectWorking.Top + m_rectWorking.Height / 2); 42  43             List<List<PointF>> lstRingPoints = new List<List<PointF>>(splitCount); 44             //分割點 45             for (int i = 0; i < radarPositions.Length; i++) 46             { 47                 float fltAngle = 270 + fltSplitAngle * i; 48                 fltAngle = fltAngle % 360; 49                 for (int j = 0; j < splitCount; j++) 50                 { 51                     if (i == 0) 52                     { 53                         lstRingPoints.Add(new List<PointF>()); 54                     } 55                     PointF _point = GetPointByAngle(centrePoint, fltAngle, fltSplitRadiusWidth * (splitCount - j)); 56                     lstRingPoints[j].Add(_point); 57                 } 58             } 59  60             for (int i = 0; i < lstRingPoints.Count; i++) 61             { 62                 var ring = lstRingPoints[i]; 63                 GraphicsPath path = new GraphicsPath(); 64                 path.AddLines(ring.ToArray()); 65                 if ((lstRingPoints.Count - i) % 2 == 0) 66                 { 67                     g.FillPath(new SolidBrush(splitEvenColor), path); 68                 } 69                 else 70                 { 71                     g.FillPath(new SolidBrush(splitOddColor), path); 72                 } 73             } 74  75             //畫環 76             foreach (var ring in lstRingPoints) 77             { 78                 ring.Add(ring[0]); 79                 g.DrawLines(new Pen(new SolidBrush(lineColor)), ring.ToArray()); 80             } 81             //分割線 82             foreach (var item in lstRingPoints[0]) 83             { 84                 g.DrawLine(new Pen(new SolidBrush(lineColor)), centrePoint, item); 85             } 86  87             // 88             for (int i = 0; i < lines.Length; i++) 89             { 90                 var line = lines[i]; 91                 if (line.Values.Length != radarPositions.Length)//如果資料長度和節點長度不一致則不繪制 92                     continue; 93                 if (line.LineColor == null || line.LineColor == Color.Empty || line.LineColor == Color.Transparent) 94                     line.LineColor = ControlHelper.Colors[i + 13]; 95                 List<PointF> ps = new List<PointF>(); 96                 for (int j = 0; j < radarPositions.Length; j++) 97                 { 98                     float fltAngle = 270 + fltSplitAngle * j; 99                     fltAngle = fltAngle % 360;100                     PointF _point = GetPointByAngle(centrePoint, fltAngle, fltRadiusWidth * (float)(line.Values[j] / radarPositions[i].MaxValue));101                     ps.Add(_point);102                 }103                 ps.Add(ps[0]);104                 if (line.FillColor != null && line.FillColor != Color.Empty && line.FillColor != Color.Transparent)105                 {106                     GraphicsPath path = new GraphicsPath();107                     path.AddLines(ps.ToArray());108                     g.FillPath(new SolidBrush(line.FillColor.Value), path);109                 }110                 g.DrawLines(new Pen(new SolidBrush(line.LineColor.Value), 2), ps.ToArray());111 112                 for (int j = 0; j < radarPositions.Length; j++)113                 {114                     var item = ps[j];115                     g.FillEllipse(new SolidBrush(Color.White), new RectangleF(item.X - 3, item.Y - 3, 6, 6));116                     g.DrawEllipse(new Pen(new SolidBrush(line.LineColor.Value)), new RectangleF(item.X - 3, item.Y - 3, 6, 6));117                     if (line.ShowValueText)118                     {119                         var valueSize = g.MeasureString(line.Values[j].ToString("0.##"), Font);120                         g.DrawString(line.Values[j].ToString("0.##"), Font, new SolidBrush(line.LineColor.Value), new PointF(item.X - valueSize.Width / 2, item.Y - valueSize.Height - 5));121                     }122                 }123             }124 125             //文本126 127             for (int i = 0; i < radarPositions.Length; i++)128             {129                 PointF point = lstRingPoints[0][i];130                 var txtSize = g.MeasureString(radarPositions[i].Text, Font);131 132                 if (point.X == centrePoint.X)133                 {134                     if (point.Y > centrePoint.Y)135                     {136                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X - txtSize.Width / 2, point.Y + 10));137                     }138                     else139                     {140                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X - txtSize.Width / 2, point.Y - 10 - txtSize.Height));141                     }142                 }143                 else if (point.Y == centrePoint.Y)144                 {145                     if (point.X < centrePoint.X)146                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X - 10 - txtSize.Width, point.Y - txtSize.Height / 2));147                     else148                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X + 10, point.Y - txtSize.Height / 2));149                 }150                 else if (point.X < centrePoint.X)//151                 {152                     if (point.Y < centrePoint.Y)//左上153                     {154                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X - 10 - txtSize.Width, point.Y - 10 + txtSize.Height / 2));155                     }156                     else//左下157                     {158                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X - 10 - txtSize.Width, point.Y + 10 - txtSize.Height / 2));159                     }160                 }161                 else162                 {163                     if (point.Y < centrePoint.Y)//右上164                     {165                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X + 10, point.Y - 10 + txtSize.Height / 2));166                     }167                     else//右下168                     {169                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X + 10, point.Y + 10 - txtSize.Height / 2));170                     }171                 }172             }173 174         }

輔助函式

 1  #region 根據中心點、角度、半徑計算圓邊坐標點    English:Calculating the coordinate points of circular edge according to the center point, angle and radius 2         /// <summary> 3         /// 功能描述:根據中心點、角度、半徑計算圓邊坐標點    English:Calculating the coordinate points of circular edge according to the center point, angle and radius 4         /// 作  者:HZH 5         /// 創建日期:2019-09-25 09:46:32 6         /// 任務編號:POS 7         /// </summary> 8         /// <param name="centrePoint">centrePoint</param> 9         /// <param name="fltAngle">fltAngle</param>10         /// <param name="fltRadiusWidth">fltRadiusWidth</param>11         /// <returns>回傳值</returns>12         private PointF GetPointByAngle(PointF centrePoint, float fltAngle, float fltRadiusWidth)13         {14             PointF p = centrePoint;15             if (fltAngle == 0)16             {17                 p.X += fltRadiusWidth;18             }19             else if (fltAngle == 90)20             {21                 p.Y += fltRadiusWidth;22             }23             else if (fltAngle == 180)24             {25                 p.X -= fltRadiusWidth;26             }27             else if (fltAngle == 270)28             {29                 p.Y -= fltRadiusWidth;30             }31             else if (fltAngle > 0 && fltAngle < 90)32             {33                 p.Y += (float)Math.Sin(Math.PI * (fltAngle / 180.00F)) * fltRadiusWidth;34                 p.X += (float)Math.Cos(Math.PI * (fltAngle / 180.00F)) * fltRadiusWidth;35             }36             else if (fltAngle > 90 && fltAngle < 180)37             {38                 p.Y += (float)Math.Sin(Math.PI * ((180 - fltAngle) / 180.00F)) * fltRadiusWidth;39                 p.X -= (float)Math.Cos(Math.PI * ((180 - fltAngle) / 180.00F)) * fltRadiusWidth;40             }41             else if (fltAngle > 180 && fltAngle < 270)42             {43                 p.Y -= (float)Math.Sin(Math.PI * ((fltAngle - 180) / 180.00F)) * fltRadiusWidth;44                 p.X -= (float)Math.Cos(Math.PI * ((fltAngle - 180) / 180.00F)) * fltRadiusWidth;45             }46             else if (fltAngle > 270 && fltAngle < 360)47             {48                 p.Y -= (float)Math.Sin(Math.PI * ((360 - fltAngle) / 180.00F)) * fltRadiusWidth;49                 p.X += (float)Math.Cos(Math.PI * ((360 - fltAngle) / 180.00F)) * fltRadiusWidth;50             }51             return p;52         }53         #endregion54 55         /// <summary>56         /// Resets the size of the title.57         /// </summary>58         private void ResetTitleSize()59         {60             if (!string.IsNullOrEmpty(title))61             {62                 using (Graphics g = this.CreateGraphics())63                 {64                     titleSize = g.MeasureString(title, titleFont);65                 }66             }67             else68             {69                 titleSize = SizeF.Empty;70             }71             titleSize.Height += 20;72             ResetWorkingRect();73         }

完整代碼

  1 // ***********************************************************************  2 // Assembly         : HZH_Controls  3 // Created          : 2019-09-25  4 //  5 // ***********************************************************************  6 // <copyright file="UCRadarChart.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.Collections.Generic; 18 using System.Linq; 19 using System.Text; 20 using System.Windows.Forms; 21 using System.Drawing; 22 using System.Drawing.Drawing2D; 23 using System.ComponentModel; 24  25 namespace HZH_Controls.Controls 26 { 27     /// <summary> 28     /// Class UCRadarChart. 29     /// Implements the <see cref="System.Windows.Forms.UserControl" /> 30     /// </summary> 31     /// <seealso cref="System.Windows.Forms.UserControl" /> 32     public class UCRadarChart : UserControl 33     { 34         /// <summary> 35         /// The split count 36         /// </summary> 37         private int splitCount = 5; 38         /// <summary> 39         /// Gets or sets the split count. 40         /// </summary> 41         /// <value>The split count.</value> 42         [Browsable(true)] 43         [Category("自定義")] 44         [Description("獲取或設定分隔份數")] 45         public int SplitCount 46         { 47             get { return splitCount; } 48             set 49             { 50                 splitCount = value; 51                 Invalidate(); 52             } 53         } 54  55         /// <summary> 56         /// The split odd color 57         /// </summary> 58         private Color splitOddColor = Color.White; 59         /// <summary> 60         /// 分隔奇數欄背景色 61         /// </summary> 62         /// <value>The color of the split odd.</value> 63         [Browsable(true)] 64         [Category("自定義")] 65         [Description("獲取或設定分隔奇數欄背景色")] 66         public Color SplitOddColor 67         { 68             get { return splitOddColor; } 69             set 70             { 71                 splitOddColor = value; 72                 Invalidate(); 73             } 74         } 75         /// <summary> 76         /// The split even color 77         /// </summary> 78         private Color splitEvenColor = Color.FromArgb(232, 232, 232); 79         /// <summary> 80         /// 分隔偶數欄背景色 81         /// </summary> 82         /// <value>The color of the split even.</value> 83         [Browsable(true)] 84         [Category("自定義")] 85         [Description("獲取或設定分隔偶數欄背景色")] 86         public Color SplitEvenColor 87         { 88             get { return splitEvenColor; } 89             set { splitEvenColor = value; } 90         } 91  92         /// <summary> 93         /// The line color 94         /// </summary> 95         private Color lineColor = Color.FromArgb(153, 153, 153); 96         /// <summary> 97         /// Gets or sets the color of the line. 98         /// </summary> 99         /// <value>The color of the line.</value>100         [Browsable(true)]101         [Category("自定義")]102         [Description("獲取或設定線條色")]103         public Color LineColor104         {105             get { return lineColor; }106             set107             {108                 lineColor = value;109                 Invalidate();110             }111         }112 113         /// <summary>114         /// The radar positions115         /// </summary>116         private RadarPosition[] radarPositions;117         /// <summary>118         /// 節點串列,至少需要3個119         /// </summary>120         /// <value>The radar positions.</value>121         [Browsable(true)]122         [Category("自定義")]123         [Description("獲取或設定節點,至少需要3個")]124         public RadarPosition[] RadarPositions125         {126             get { return radarPositions; }127             set128             {129                 radarPositions = value;130                 Invalidate();131             }132         }133 134         /// <summary>135         /// The title136         /// </summary>137         private string title;138         /// <summary>139         /// 標題140         /// </summary>141         /// <value>The title.</value>142         [Browsable(true)]143         [Category("自定義")]144         [Description("獲取或設定標題")]145         public string Title146         {147             get { return title; }148             set149             {150                 title = value;151                 ResetTitleSize();152                 Invalidate();153             }154         }155 156         /// <summary>157         /// The title font158         /// </summary>159         private Font titleFont = new Font("微軟雅黑", 12);160         /// <summary>161         /// Gets or sets the title font.162         /// </summary>163         /// <value>The title font.</value>164         [Browsable(true)]165         [Category("自定義")]166         [Description("獲取或設定標題字體")]167         public Font TitleFont168         {169             get { return titleFont; }170             set171             {172                 titleFont = value;173                 ResetTitleSize();174                 Invalidate();175             }176         }177 178         /// <summary>179         /// The title color180         /// </summary>181         private Color titleColor = Color.Black;182         /// <summary>183         /// Gets or sets the color of the title.184         /// </summary>185         /// <value>The color of the title.</value>186         [Browsable(true)]187         [Category("自定義")]188         [Description("獲取或設定標題文本顏色")]189         public Color TitleColor190         {191             get { return titleColor; }192             set193             {194                 titleColor = value;195                 Invalidate();196             }197         }198 199         /// <summary>200         /// The lines201         /// </summary>202         private RadarLine[] lines;203         /// <summary>204         /// Gets or sets the lines.205         /// </summary>206         /// <value>The lines.</value>207         [Browsable(true)]208         [Category("自定義")]209         [Description("獲取或設定值線條,Values長度必須與RadarPositions長度一致,否則無法顯示")]210         public RadarLine[] Lines211         {212             get { return lines; }213             set214             {215                 lines = value;216                 Invalidate();217             }218         }219 220 221         /// <summary>222         /// The title size223         /// </summary>224         SizeF titleSize = SizeF.Empty;225         /// <summary>226         /// The m rect working227         /// </summary>228         private RectangleF m_rectWorking = Rectangle.Empty;229         /// <summary>230         /// The line value type size231         /// </summary>232         SizeF lineValueTypeSize = SizeF.Empty;233         /// <summary>234         /// The int line value COM count235         /// </summary>236         int intLineValueComCount = 0;237         /// <summary>238         /// The int line value row count239         /// </summary>240         int intLineValueRowCount = 0;241         /// <summary>242         /// Initializes a new instance of the <see cref="UCRadarChart"/> class.243         /// </summary>244         public UCRadarChart()245         {246             this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);247             this.SetStyle(ControlStyles.DoubleBuffer, true);248             this.SetStyle(ControlStyles.ResizeRedraw, true);249             this.SetStyle(ControlStyles.Selectable, true);250             this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);251             this.SetStyle(ControlStyles.UserPaint, true);252             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;253             this.SizeChanged += UCRadarChart_SizeChanged;254             Size = new System.Drawing.Size(150, 150);255             radarPositions = new RadarPosition[0];256             if (ControlHelper.IsDesignMode())257             {258                 radarPositions = new RadarPosition[6];259                 for (int i = 0; i < 6; i++)260                 {261                     radarPositions[i] = new RadarPosition262                     {263                         Text = "Item" + (i + 1),264                         MaxValue = https://www.cnblogs.com/bfyx/p/100265                     };266                 }267             }268 269             lines = new RadarLine[0];270             if (ControlHelper.IsDesignMode())271             {272                 Random r = new Random();273                 lines = new RadarLine[2];274                 for (int i = 0; i < 2; i++)275                 {276                     lines[i] = new RadarLine()277                     {278                         Name = "line" + i279                     };280                     lines[i].Values = new double[radarPositions.Length];281                     for (int j = 0; j < radarPositions.Length; j++)282                     {283                         lines[i].Values[j] = r.Next(20, (int)radarPositions[j].MaxValue);284                     }285                 }286             }287         }288 289         /// <summary>290         /// Handles the SizeChanged event of the UCRadarChart control.291         /// </summary>292         /// <param name="sender">The source of the event.</param>293         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>294         void UCRadarChart_SizeChanged(object sender, EventArgs e)295         {296             ResetWorkingRect();297         }298 299         /// <summary>300         /// Resets the working rect.301         /// </summary>302         private void ResetWorkingRect()303         {304             if (lines != null && lines.Length > 0)305             {306                 using (Graphics g = this.CreateGraphics())307                 {308                     foreach (var item in lines)309                     {310                         var s = g.MeasureString(item.Name, Font);311                         if (s.Width > lineValueTypeSize.Width)312                             lineValueTypeSize = s;313                     }314                 }315             }316             var lineTypePanelHeight = 0f;317             if (lineValueTypeSize != SizeF.Empty)318             {319                 intLineValueComCount = (int)(this.Width / (lineValueTypeSize.Width + 25));320 321                 intLineValueRowCount = lines.Length / intLineValueComCount;322                 if (lines.Length % intLineValueComCount != 0)323                 {324                     intLineValueRowCount++;325                 }326                 lineTypePanelHeight = (lineValueTypeSize.Height + 10) * intLineValueRowCount;327             }328             var min = Math.Min(this.Width, this.Height - titleSize.Height - lineTypePanelHeight);329             var rectWorking = new RectangleF((this.Width - min) / 2 + 10, titleSize.Height + lineTypePanelHeight + 10, min - 10, min - 10);330             //處理文字331             float fltSplitAngle = 360F / radarPositions.Length;332             float fltRadiusWidth = rectWorking.Width / 2;333             float minX = rectWorking.Left;334             float maxX = rectWorking.Right;335             float minY = rectWorking.Top;336             float maxY = rectWorking.Bottom;337             using (Graphics g = this.CreateGraphics())338             {339                 PointF centrePoint = new PointF(rectWorking.Left + rectWorking.Width / 2, rectWorking.Top + rectWorking.Height / 2);340                 for (int i = 0; i < radarPositions.Length; i++)341                 {342                     float fltAngle = 270 + fltSplitAngle * i;343                     fltAngle = fltAngle % 360;344                     PointF _point = GetPointByAngle(centrePoint, fltAngle, fltRadiusWidth);345                     var _txtSize = g.MeasureString(radarPositions[i].Text, Font);346                     if (_point.X < centrePoint.X)//347                     {348                         if (_point.X - _txtSize.Width < minX)349                         {350                             minX = rectWorking.Left + _txtSize.Width;351                         }352                     }353                     else//354                     {355                         if (_point.X + _txtSize.Width > maxX)356                         {357                             maxX = rectWorking.Right - _txtSize.Width;358                         }359                     }360                     if (_point.Y < centrePoint.Y)//361                     {362                         if (_point.Y - _txtSize.Height < minY)363                         {364                             minY = rectWorking.Top + _txtSize.Height;365                         }366                     }367                     else//368                     {369                         if (_point.Y + _txtSize.Height > maxY)370                         {371                             maxY = rectWorking.Bottom - _txtSize.Height;372                         }373                     }374                 }375             }376 377             min = Math.Min(maxX - minX, maxY - minY);378             m_rectWorking = new RectangleF(minX, minY, min, min);379         }380 381         /// <summary>382         /// 引發 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件,383         /// </summary>384         /// <param name="e">包含事件資料的 <see cref="T:System.Windows.Forms.PaintEventArgs" /></param>385         protected override void OnPaint(PaintEventArgs e)386         {387             base.OnPaint(e);388             var g = e.Graphics;389             g.SetGDIHigh();390 391             if (!string.IsNullOrEmpty(title))392             {393                 g.DrawString(title, titleFont, new SolidBrush(titleColor), new RectangleF(m_rectWorking.Left + (m_rectWorking.Width - titleSize.Width) / 2, m_rectWorking.Top - titleSize.Height - 10 - (intLineValueRowCount * (10 + lineValueTypeSize.Height)), titleSize.Width, titleSize.Height));394             }395 396             if (radarPositions.Length <= 2)397             {398                 g.DrawString("至少需要3個頂點", Font, new SolidBrush(Color.Black), m_rectWorking, new StringFormat() { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center });399                 return;400             }401 402             var y = m_rectWorking.Top - 20 - (intLineValueRowCount * (10 + lineValueTypeSize.Height));403 404             for (int i = 0; i < intLineValueRowCount; i++)405             {406                 var x = 0f;407                 int intCount = intLineValueComCount;408                 if (i == intLineValueRowCount - 1)409                 {410                     intCount = lines.Length % intLineValueComCount;411 412                 }413                 x = m_rectWorking.Left + (m_rectWorking.Width - intCount * (lineValueTypeSize.Width + 25)) / 2;414 415                 for (int j = 0; j < intCount; j++)416                 {417                     g.FillRectangle(new SolidBrush(lines[i * intLineValueComCount + j].LineColor.Value), new RectangleF(x + (lineValueTypeSize.Width + 25)*j, y + lineValueTypeSize.Height * i, 15, lineValueTypeSize.Height));418                     g.DrawString(lines[i * intLineValueComCount + j].Name, Font, new SolidBrush(lines[i * intLineValueComCount + j].LineColor.Value), new PointF(x + (lineValueTypeSize.Width + 25) * j + 20, y + lineValueTypeSize.Height * i));419                 }420             }421 422             float fltSplitAngle = 360F / radarPositions.Length;423             float fltRadiusWidth = m_rectWorking.Width / 2;424             float fltSplitRadiusWidth = fltRadiusWidth / splitCount;425             PointF centrePoint = new PointF(m_rectWorking.Left + m_rectWorking.Width / 2, m_rectWorking.Top + m_rectWorking.Height / 2);426 427             List<List<PointF>> lstRingPoints = new List<List<PointF>>(splitCount);428             //分割點429             for (int i = 0; i < radarPositions.Length; i++)430             {431                 float fltAngle = 270 + fltSplitAngle * i;432                 fltAngle = fltAngle % 360;433                 for (int j = 0; j < splitCount; j++)434                 {435                     if (i == 0)436                     {437                         lstRingPoints.Add(new List<PointF>());438                     }439                     PointF _point = GetPointByAngle(centrePoint, fltAngle, fltSplitRadiusWidth * (splitCount - j));440                     lstRingPoints[j].Add(_point);441                 }442             }443 444             for (int i = 0; i < lstRingPoints.Count; i++)445             {446                 var ring = lstRingPoints[i];447                 GraphicsPath path = new GraphicsPath();448                 path.AddLines(ring.ToArray());449                 if ((lstRingPoints.Count - i) % 2 == 0)450                 {451                     g.FillPath(new SolidBrush(splitEvenColor), path);452                 }453                 else454                 {455                     g.FillPath(new SolidBrush(splitOddColor), path);456                 }457             }458 459             //畫環460             foreach (var ring in lstRingPoints)461             {462                 ring.Add(ring[0]);463                 g.DrawLines(new Pen(new SolidBrush(lineColor)), ring.ToArray());464             }465             //分割線466             foreach (var item in lstRingPoints[0])467             {468                 g.DrawLine(new Pen(new SolidBrush(lineColor)), centrePoint, item);469             }470 471             //472             for (int i = 0; i < lines.Length; i++)473             {474                 var line = lines[i];475                 if (line.Values.Length != radarPositions.Length)//如果資料長度和節點長度不一致則不繪制476                     continue;477                 if (line.LineColor == null || line.LineColor == Color.Empty || line.LineColor == Color.Transparent)478                     line.LineColor = ControlHelper.Colors[i + 13];479                 List<PointF> ps = new List<PointF>();480                 for (int j = 0; j < radarPositions.Length; j++)481                 {482                     float fltAngle = 270 + fltSplitAngle * j;483                     fltAngle = fltAngle % 360;484                     PointF _point = GetPointByAngle(centrePoint, fltAngle, fltRadiusWidth * (float)(line.Values[j] / radarPositions[i].MaxValue));485                     ps.Add(_point);486                 }487                 ps.Add(ps[0]);488                 if (line.FillColor != null && line.FillColor != Color.Empty && line.FillColor != Color.Transparent)489                 {490                     GraphicsPath path = new GraphicsPath();491                     path.AddLines(ps.ToArray());492                     g.FillPath(new SolidBrush(line.FillColor.Value), path);493                 }494                 g.DrawLines(new Pen(new SolidBrush(line.LineColor.Value), 2), ps.ToArray());495 496                 for (int j = 0; j < radarPositions.Length; j++)497                 {498                     var item = ps[j];499                     g.FillEllipse(new SolidBrush(Color.White), new RectangleF(item.X - 3, item.Y - 3, 6, 6));500                     g.DrawEllipse(new Pen(new SolidBrush(line.LineColor.Value)), new RectangleF(item.X - 3, item.Y - 3, 6, 6));501                     if (line.ShowValueText)502                     {503                         var valueSize = g.MeasureString(line.Values[j].ToString("0.##"), Font);504                         g.DrawString(line.Values[j].ToString("0.##"), Font, new SolidBrush(line.LineColor.Value), new PointF(item.X - valueSize.Width / 2, item.Y - valueSize.Height - 5));505                     }506                 }507             }508 509             //文本510 511             for (int i = 0; i < radarPositions.Length; i++)512             {513                 PointF point = lstRingPoints[0][i];514                 var txtSize = g.MeasureString(radarPositions[i].Text, Font);515 516                 if (point.X == centrePoint.X)517                 {518                     if (point.Y > centrePoint.Y)519                     {520                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X - txtSize.Width / 2, point.Y + 10));521                     }522                     else523                     {524                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X - txtSize.Width / 2, point.Y - 10 - txtSize.Height));525                     }526                 }527                 else if (point.Y == centrePoint.Y)528                 {529                     if (point.X < centrePoint.X)530                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X - 10 - txtSize.Width, point.Y - txtSize.Height / 2));531                     else532                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X + 10, point.Y - txtSize.Height / 2));533                 }534                 else if (point.X < centrePoint.X)//535                 {536                     if (point.Y < centrePoint.Y)//左上537                     {538                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X - 10 - txtSize.Width, point.Y - 10 + txtSize.Height / 2));539                     }540                     else//左下541                     {542                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X - 10 - txtSize.Width, point.Y + 10 - txtSize.Height / 2));543                     }544                 }545                 else546                 {547                     if (point.Y < centrePoint.Y)//右上548                     {549                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X + 10, point.Y - 10 + txtSize.Height / 2));550                     }551                     else//右下552                     {553                         g.DrawString(radarPositions[i].Text, Font, new SolidBrush(ForeColor), new PointF(point.X + 10, point.Y + 10 - txtSize.Height / 2));554                     }555                 }556             }557 558         }559 560         #region 根據中心點、角度、半徑計算圓邊坐標點    English:Calculating the coordinate points of circular edge according to the center point, angle and radius561         /// <summary>562         /// 功能描述:根據中心點、角度、半徑計算圓邊坐標點    English:Calculating the coordinate points of circular edge according to the center point, angle and radius563         /// 作  者:HZH564         /// 創建日期:2019-09-25 09:46:32565         /// 任務編號:POS566         /// </summary>567         /// <param name="centrePoint">centrePoint</param>568         /// <param name="fltAngle">fltAngle</param>569         /// <param name="fltRadiusWidth">fltRadiusWidth</param>570         /// <returns>回傳值</returns>571         private PointF GetPointByAngle(PointF centrePoint, float fltAngle, float fltRadiusWidth)572         {573             PointF p = centrePoint;574             if (fltAngle == 0)575             {576                 p.X += fltRadiusWidth;577             }578             else if (fltAngle == 90)579             {580                 p.Y += fltRadiusWidth;581             }582             else if (fltAngle == 180)583             {584                 p.X -= fltRadiusWidth;585             }586             else if (fltAngle == 270)587             {588                 p.Y -= fltRadiusWidth;589             }590             else if (fltAngle > 0 && fltAngle < 90)591             {592                 p.Y += (float)Math.Sin(Math.PI * (fltAngle / 180.00F)) * fltRadiusWidth;593                 p.X += (float)Math.Cos(Math.PI * (fltAngle / 180.00F)) * fltRadiusWidth;594             }595             else if (fltAngle > 90 && fltAngle < 180)596             {597                 p.Y += (float)Math.Sin(Math.PI * ((180 - fltAngle) / 180.00F)) * fltRadiusWidth;598                 p.X -= (float)Math.Cos(Math.PI * ((180 - fltAngle) / 180.00F)) * fltRadiusWidth;599             }600             else if (fltAngle > 180 && fltAngle < 270)601             {602                 p.Y -= (float)Math.Sin(Math.PI * ((fltAngle - 180) / 180.00F)) * fltRadiusWidth;603                 p.X -= (float)Math.Cos(Math.PI * ((fltAngle - 180) / 180.00F)) * fltRadiusWidth;604             }605             else if (fltAngle > 270 && fltAngle < 360)606             {607                 p.Y -= (float)Math.Sin(Math.PI * ((360 - fltAngle) / 180.00F)) * fltRadiusWidth;608                 p.X += (float)Math.Cos(Math.PI * ((360 - fltAngle) / 180.00F)) * fltRadiusWidth;609             }610             return p;611         }612         #endregion613 614         /// <summary>615         /// Resets the size of the title.616         /// </summary>617         private void ResetTitleSize()618         {619             if (!string.IsNullOrEmpty(title))620             {621                 using (Graphics g = this.CreateGraphics())622                 {623                     titleSize = g.MeasureString(title, titleFont);624                 }625             }626             else627             {628                 titleSize = SizeF.Empty;629             }630             titleSize.Height += 20;631             ResetWorkingRect();632         }633     }634 }
View Code

 

最后的話

如果你喜歡的話,請到 https://gitee.com/kwwwvagaa/net_winform_custom_control 點個星星吧

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/6458.html

標籤:WinForm

上一篇:Winform中對xml檔案進行保存時空白節點自動換行問題的解決

下一篇:Winform中實作設定ZedGraph的GraphPane的大小匹配ZedGraphControl

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • WebAPI簡介

    Web體系結構: 有三個核心:資源(resource),URL(統一資源識別符號)和表示 他們的關系是這樣的:一個資源由一個URL進行標識,HTTP客戶端使用URL定位資源,表示是從資源回傳資料,媒體型別是資源回傳的資料格式。 接下來我們說下HTTP. HTTP協議的系統是一種無狀態的方式,使用請求/ ......

    uj5u.com 2020-09-09 22:07:47 more
  • asp.net core 3.1 入口:Program.cs中的Main函式

    本文分析Program.cs 中Main()函式中代碼的運行順序分析asp.net core程式的啟動,重點不是剖析原始碼,而是理清程式開始時執行的順序。到呼叫了哪些實體,哪些法方。asp.net core 3.1 的程式入口在專案Program.cs檔案里,如下。ususing System; us ......

    uj5u.com 2020-09-09 22:07:49 more
  • asp.net網站作為websocket服務端的應用該如何寫

    最近被websocket的一個問題困擾了很久,有一個需求是在web網站中搭建websocket服務。客戶端通過網頁與服務器建立連接,然后服務器根據ip給客戶端網頁發送資訊。 其實,這個需求并不難,只是剛開始對websocket的內容不太了解。上網搜索了一下,有通過asp.net core 實作的、有 ......

    uj5u.com 2020-09-09 22:08:02 more
  • ASP.NET 開源匯入匯出庫Magicodes.IE Docker中使用

    Magicodes.IE在Docker中使用 更新歷史 2019.02.13 【Nuget】版本更新到2.0.2 【匯入】修復單列匯入的Bug,單元測驗“OneColumnImporter_Test”。問題見(https://github.com/dotnetcore/Magicodes.IE/is ......

    uj5u.com 2020-09-09 22:08:05 more
  • 在webform中使用ajax

    如果你用過Asp.net webform, 說明你也算是.NET 開發的老兵了。WEBform應該是2011 2013左右,當時還用visual studio 2005、 visual studio 2008。后來基本都用的是MVC。 如果是新開發的專案,估計沒人會用webform技術。但是有些舊版 ......

    uj5u.com 2020-09-09 22:08:50 more
  • iis添加asp.net網站,訪問提示:由于擴展配置問題而無法提供您請求的

    今天在iis服務器配置asp.net網站,遇到一個問題,記錄一下: 問題:由于擴展配置問題而無法提供您請求的頁面。如果該頁面是腳本,請添加處理程式。如果應下載檔案,請添加 MIME 映射。 WindowServer2012服務器,添加角色安裝完.netframework和iis之后,運行aspx頁面 ......

    uj5u.com 2020-09-09 22:10:00 more
  • WebAPI-處理架構

    帶著問題去思考,大家好! 問題1:HTTP請求和回傳相應的HTTP回應資訊之間發生了什么? 1:首先是最底層,托管層,位于WebAPI和底層HTTP堆疊之間 2:其次是 訊息處理程式管道層,這里比如日志和快取。OWIN的參考是將訊息處理程式管道的一些功能下移到堆疊下端的OWIN中間件了。 3:控制器處理 ......

    uj5u.com 2020-09-09 22:11:13 more
  • 微信門戶開發框架-使用指導說明書

    微信門戶應用管理系統,采用基于 MVC + Bootstrap + Ajax + Enterprise Library的技術路線,界面層采用Boostrap + Metronic組合的前端框架,資料訪問層支持Oracle、SQLServer、MySQL、PostgreSQL等資料庫。框架以MVC5,... ......

    uj5u.com 2020-09-09 22:15:18 more
  • WebAPI-HTTP編程模型

    帶著問題去思考,大家好!它是什么?它包含什么?它能干什么? 訊息 HTTP編程模型的核心就是訊息抽象,表示為:HttPRequestMessage,HttpResponseMessage.用于客戶端和服務端之間交換請求和回應訊息。 HttpMethod類包含了一組靜態屬性: private stat ......

    uj5u.com 2020-09-09 22:15:23 more
  • 部署WebApi隨筆

    一、跨域 NuGet參考Microsoft.AspNet.WebApi.Cors WebApiConfig.cs中配置: // Web API 配置和服務 config.EnableCors(new EnableCorsAttribute("*", "*", "*")); 二、清除默認回傳XML格式 ......

    uj5u.com 2020-09-09 22:15:48 more
最新发布
  • C#多執行緒學習(二) 如何操縱一個執行緒

    <a href="https://www.cnblogs.com/x-zhi/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2943582/20220801082530.png" alt="" /></...

    uj5u.com 2023-04-19 09:17:20 more
  • C#多執行緒學習(二) 如何操縱一個執行緒

    C#多執行緒學習(二) 如何操縱一個執行緒 執行緒學習第一篇:C#多執行緒學習(一) 多執行緒的相關概念 下面我們就動手來創建一個執行緒,使用Thread類創建執行緒時,只需提供執行緒入口即可。(執行緒入口使程式知道該讓這個執行緒干什么事) 在C#中,執行緒入口是通過ThreadStart代理(delegate)來提供的 ......

    uj5u.com 2023-04-19 09:16:49 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    <a href="https://www.cnblogs.com/huangxincheng/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/214741/20200614104537.png" alt="" /&g...

    uj5u.com 2023-04-18 08:39:04 more
  • 記一次 .NET某醫療器械清洗系統 卡死分析

    一:背景 1. 講故事 前段時間協助訓練營里的一位朋友分析了一個程式卡死的問題,回過頭來看這個案例比較經典,這篇稍微整理一下供后來者少踩坑吧。 二:WinDbg 分析 1. 為什么會卡死 因為是表單程式,理所當然就是看主執行緒此時正在做什么? 可以用 ~0s ; k 看一下便知。 0:000> k # ......

    uj5u.com 2023-04-18 08:33:10 more
  • SignalR, No Connection with that ID,IIS

    <a href="https://www.cnblogs.com/smartstar/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/u36196.jpg" alt="" /></a>...

    uj5u.com 2023-03-30 17:21:52 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:15:33 more
  • 一次對pool的誤用導致的.net頻繁gc的診斷分析

    <a href="https://www.cnblogs.com/dotnet-diagnostic/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/3115652/20230225090434.png" alt=""...

    uj5u.com 2023-03-28 10:13:31 more
  • C#遍歷指定檔案夾中所有檔案的3種方法

    <a href="https://www.cnblogs.com/xbhp/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/957602/20230310105611.png" alt="" /></a&...

    uj5u.com 2023-03-27 14:46:55 more
  • C#/VB.NET:如何將PDF轉為PDF/A

    <a href="https://www.cnblogs.com/Carina-baby/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/2859233/20220427162558.png" alt="" />...

    uj5u.com 2023-03-27 14:46:35 more
  • 武裝你的WEBAPI-OData聚合查詢

    <a href="https://www.cnblogs.com/podolski/" target="_blank"><img width="48" height="48" class="pfs" src="https://pic.cnblogs.com/face/616093/20140323000327.png" alt="" /><...

    uj5u.com 2023-03-27 14:46:16 more