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


    官网

    http://www.hzhcontrols.com

    前提

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

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

    码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

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

    欢迎前来交流探讨: 企鹅群568015492 企鹅群568015492

    目录

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

    准备工作

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

    开始

    添加一个用户控件,命名UCProcessEllipse

    定义2个枚举

     1  public enum ValueType
     2     {
     3         /// <summary>
     4         /// 百分比
     5         /// </summary>
     6         Percent,
     7         /// <summary>
     8         /// 数值
     9         /// </summary>
    10         Absolute
    11     }
    12 
    13     public enum ShowType
    14     {
    15         /// <summary>
    16         /// 圆环
    17         /// </summary>
    18         Ring,
    19         /// <summary>
    20         /// 扇形
    21         /// </summary>
    22         Sector
    23     }

    添加属性

      1  [Description("值改变事件"), Category("自定义")]
      2         public event EventHandler ValueChanged;
      3 
      4         private Color m_backEllipseColor = Color.FromArgb(22, 160, 133);
      5         /// <summary>
      6         /// 圆背景色
      7         /// </summary>
      8         [Description("圆背景色"), Category("自定义")]
      9         public Color BackEllipseColor
     10         {
     11             get { return m_backEllipseColor; }
     12             set
     13             {
     14                 m_backEllipseColor = value;
     15                 Refresh();
     16             }
     17         }
     18 
     19         private Color m_coreEllipseColor = Color.FromArgb(180, 180, 180);
     20         /// <summary>
     21         /// 内圆颜色,ShowType=Ring 有效
     22         /// </summary>
     23         [Description("内圆颜色,ShowType=Ring 有效"), Category("自定义")]
     24         public Color CoreEllipseColor
     25         {
     26             get { return m_coreEllipseColor; }
     27             set
     28             {
     29                 m_coreEllipseColor = value;
     30                 Refresh();
     31             }
     32         }
     33 
     34         private Color m_valueColor = Color.FromArgb(255, 77, 59);
     35 
     36         [Description("值圆颜色"), Category("自定义")]
     37         public Color ValueColor
     38         {
     39             get { return m_valueColor; }
     40             set
     41             {
     42                 m_valueColor = value;
     43                 Refresh();
     44             }
     45         }
     46 
     47         private bool m_isShowCoreEllipseBorder = true;
     48         /// <summary>
     49         /// 内圆是否显示边框,ShowType=Ring 有效
     50         /// </summary>
     51         [Description("内圆是否显示边框,ShowType=Ring 有效"), Category("自定义")]
     52         public bool IsShowCoreEllipseBorder
     53         {
     54             get { return m_isShowCoreEllipseBorder; }
     55             set
     56             {
     57                 m_isShowCoreEllipseBorder = value;
     58                 Refresh();
     59             }
     60         }
     61 
     62         private ValueType m_valueType = ValueType.Percent;
     63         /// <summary>
     64         /// 值文字类型
     65         /// </summary>
     66         [Description("值文字类型"), Category("自定义")]
     67         public ValueType ValueType
     68         {
     69             get { return m_valueType; }
     70             set
     71             {
     72                 m_valueType = value;
     73                 Refresh();
     74             }
     75         }
     76 
     77         private int m_valueWidth = 30;
     78         /// <summary>
     79         /// 外圆值宽度
     80         /// </summary>
     81         [Description("外圆值宽度,ShowType=Ring 有效"), Category("自定义")]
     82         public int ValueWidth
     83         {
     84             get { return m_valueWidth; }
     85             set
     86             {
     87                 if (value <= 0 || value > Math.Min(this.Width, this.Height))
     88                     return;
     89                 m_valueWidth = value;
     90                 Refresh();
     91             }
     92         }
     93 
     94         private int m_valueMargin = 5;
     95         /// <summary>
     96         /// 外圆值间距
     97         /// </summary>
     98         [Description("外圆值间距"), Category("自定义")]
     99         public int ValueMargin
    100         {
    101             get { return m_valueMargin; }
    102             set
    103             {
    104                 if (value < 0 || m_valueMargin >= m_valueWidth)
    105                     return;
    106                 m_valueMargin = value;
    107                 Refresh();
    108             }
    109         }
    110 
    111         private int m_maxValue = 100;
    112         /// <summary>
    113         /// 最大值
    114         /// </summary>
    115         [Description("最大值"), Category("自定义")]
    116         public int MaxValue
    117         {
    118             get { return m_maxValue; }
    119             set
    120             {
    121                 if (value > m_value || value <= 0)
    122                     return;
    123                 m_maxValue = value;
    124                 Refresh();
    125             }
    126         }
    127 
    128         private int m_value = 0;
    129         /// <summary>
    130         /// 当前值
    131         /// </summary>
    132         [Description("当前值"), Category("自定义")]
    133         public int Value
    134         {
    135             get { return m_value; }
    136             set
    137             {
    138                 if (m_maxValue < value || value <= 0)
    139                     return;
    140                 m_value = value;
    141                 if (ValueChanged != null)
    142                 {
    143                     ValueChanged(this, null);
    144                 }
    145                 Refresh();
    146             }
    147         }
    148         private Font m_font = new Font("Arial Unicode MS", 20);
    149         [Description("文字字体"), Category("自定义")]
    150         public override Font Font
    151         {
    152             get
    153             {
    154                 return m_font;
    155             }
    156             set
    157             {
    158                 m_font = value;
    159                 Refresh();
    160             }
    161         }
    162         Color m_foreColor = Color.White;
    163         [Description("文字颜色"), Category("自定义")]
    164         public override Color ForeColor
    165         {
    166             get
    167             {
    168                 return m_foreColor;
    169             }
    170             set
    171             {
    172                 m_foreColor = value;
    173                 Refresh();
    174             }
    175         }
    176 
    177         private ShowType m_showType = ShowType.Ring;
    178 
    179         [Description("显示类型"), Category("自定义")]
    180         public ShowType ShowType
    181         {
    182             get { return m_showType; }
    183             set
    184             {
    185                 m_showType = value;
    186                 Refresh();
    187             }
    188         }

    重绘

     1   protected override void OnPaint(PaintEventArgs e)
     2         {
     3             base.OnPaint(e);
     4 
     5             var g = e.Graphics;
     6             g.SmoothingMode = SmoothingMode.AntiAlias;  //使绘图质量最高,即消除锯齿
     7             g.InterpolationMode = InterpolationMode.HighQualityBicubic;
     8             g.CompositingQuality = CompositingQuality.HighQuality;
     9 
    10             int intWidth = Math.Min(this.Size.Width, this.Size.Height);
    11             //底圆
    12             g.FillEllipse(new SolidBrush(m_backEllipseColor), new Rectangle(new Point(0, 0), new Size(intWidth, intWidth)));
    13             if (m_showType == HZH_Controls.Controls.ShowType.Ring)
    14             {
    15                 //中心圆
    16                 int intCore = intWidth - m_valueWidth * 2;
    17                 g.FillEllipse(new SolidBrush(m_coreEllipseColor), new Rectangle(new Point(m_valueWidth, m_valueWidth), new Size(intCore, intCore)));
    18                 //中心圆边框
    19                 if (m_isShowCoreEllipseBorder)
    20                 {
    21                     g.DrawEllipse(new Pen(m_valueColor, 2), new Rectangle(new Point(m_valueWidth + 1, m_valueWidth + 1), new Size(intCore - 1, intCore - 1)));
    22                 }
    23                 if (m_value > 0 && m_maxValue > 0)
    24                 {
    25                     float fltPercent = (float)m_value / (float)m_maxValue;
    26                     if (fltPercent > 1)
    27                     {
    28                         fltPercent = 1;
    29                     }
    30 
    31                     g.DrawArc(new Pen(m_valueColor, m_valueWidth - m_valueMargin * 2), new RectangleF(new Point(m_valueWidth / 2 + m_valueMargin / 4, m_valueWidth / 2 + m_valueMargin / 4), new SizeF(intWidth - m_valueWidth - m_valueMargin / 2 + (m_valueMargin == 0 ? 0 : 1), intWidth - m_valueWidth - m_valueMargin / 2 + (m_valueMargin == 0 ? 0 : 1))), -90, fltPercent * 360);
    32 
    33                     string strValueText = m_valueType == HZH_Controls.Controls.ValueType.Percent ? fltPercent.ToString("0%") : m_value.ToString();
    34                     System.Drawing.SizeF _txtSize = g.MeasureString(strValueText, this.Font);
    35                     g.DrawString(strValueText, this.Font, new SolidBrush(this.ForeColor), new PointF((intWidth - _txtSize.Width) / 2 + 1, (intWidth - _txtSize.Height) / 2 + 1));
    36                 }
    37             }
    38             else
    39             {
    40                 if (m_value > 0 && m_maxValue > 0)
    41                 {
    42                     float fltPercent = (float)m_value / (float)m_maxValue;
    43                     if (fltPercent > 1)
    44                     {
    45                         fltPercent = 1;
    46                     }
    47 
    48                     g.FillPie(new SolidBrush(m_valueColor), new Rectangle(m_valueMargin, m_valueMargin, intWidth - m_valueMargin * 2, intWidth - m_valueMargin * 2), -90, fltPercent * 360);
    49 
    50                     string strValueText = m_valueType == HZH_Controls.Controls.ValueType.Percent ? fltPercent.ToString("0%") : m_value.ToString();
    51                     System.Drawing.SizeF _txtSize = g.MeasureString(strValueText, this.Font);
    52                     g.DrawString(strValueText, this.Font, new SolidBrush(this.ForeColor), new PointF((intWidth - _txtSize.Width) / 2 + 1, (intWidth - _txtSize.Height) / 2 + 1));
    53                 }
    54             }
    55 
    56         }

    完整代码如下

      1 using System;
      2 using System.Collections.Generic;
      3 using System.ComponentModel;
      4 using System.Drawing;
      5 using System.Data;
      6 using System.Linq;
      7 using System.Text;
      8 using System.Windows.Forms;
      9 using System.Drawing.Drawing2D;
     10 
     11 namespace HZH_Controls.Controls
     12 {
     13     public partial class UCProcessEllipse : UserControl
     14     {
     15         [Description("值改变事件"), Category("自定义")]
     16         public event EventHandler ValueChanged;
     17 
     18         private Color m_backEllipseColor = Color.FromArgb(22, 160, 133);
     19         /// <summary>
     20         /// 圆背景色
     21         /// </summary>
     22         [Description("圆背景色"), Category("自定义")]
     23         public Color BackEllipseColor
     24         {
     25             get { return m_backEllipseColor; }
     26             set
     27             {
     28                 m_backEllipseColor = value;
     29                 Refresh();
     30             }
     31         }
     32 
     33         private Color m_coreEllipseColor = Color.FromArgb(180, 180, 180);
     34         /// <summary>
     35         /// 内圆颜色,ShowType=Ring 有效
     36         /// </summary>
     37         [Description("内圆颜色,ShowType=Ring 有效"), Category("自定义")]
     38         public Color CoreEllipseColor
     39         {
     40             get { return m_coreEllipseColor; }
     41             set
     42             {
     43                 m_coreEllipseColor = value;
     44                 Refresh();
     45             }
     46         }
     47 
     48         private Color m_valueColor = Color.FromArgb(255, 77, 59);
     49 
     50         [Description("值圆颜色"), Category("自定义")]
     51         public Color ValueColor
     52         {
     53             get { return m_valueColor; }
     54             set
     55             {
     56                 m_valueColor = value;
     57                 Refresh();
     58             }
     59         }
     60 
     61         private bool m_isShowCoreEllipseBorder = true;
     62         /// <summary>
     63         /// 内圆是否显示边框,ShowType=Ring 有效
     64         /// </summary>
     65         [Description("内圆是否显示边框,ShowType=Ring 有效"), Category("自定义")]
     66         public bool IsShowCoreEllipseBorder
     67         {
     68             get { return m_isShowCoreEllipseBorder; }
     69             set
     70             {
     71                 m_isShowCoreEllipseBorder = value;
     72                 Refresh();
     73             }
     74         }
     75 
     76         private ValueType m_valueType = ValueType.Percent;
     77         /// <summary>
     78         /// 值文字类型
     79         /// </summary>
     80         [Description("值文字类型"), Category("自定义")]
     81         public ValueType ValueType
     82         {
     83             get { return m_valueType; }
     84             set
     85             {
     86                 m_valueType = value;
     87                 Refresh();
     88             }
     89         }
     90 
     91         private int m_valueWidth = 30;
     92         /// <summary>
     93         /// 外圆值宽度
     94         /// </summary>
     95         [Description("外圆值宽度,ShowType=Ring 有效"), Category("自定义")]
     96         public int ValueWidth
     97         {
     98             get { return m_valueWidth; }
     99             set
    100             {
    101                 if (value <= 0 || value > Math.Min(this.Width, this.Height))
    102                     return;
    103                 m_valueWidth = value;
    104                 Refresh();
    105             }
    106         }
    107 
    108         private int m_valueMargin = 5;
    109         /// <summary>
    110         /// 外圆值间距
    111         /// </summary>
    112         [Description("外圆值间距"), Category("自定义")]
    113         public int ValueMargin
    114         {
    115             get { return m_valueMargin; }
    116             set
    117             {
    118                 if (value < 0 || m_valueMargin >= m_valueWidth)
    119                     return;
    120                 m_valueMargin = value;
    121                 Refresh();
    122             }
    123         }
    124 
    125         private int m_maxValue = 100;
    126         /// <summary>
    127         /// 最大值
    128         /// </summary>
    129         [Description("最大值"), Category("自定义")]
    130         public int MaxValue
    131         {
    132             get { return m_maxValue; }
    133             set
    134             {
    135                 if (value > m_value || value <= 0)
    136                     return;
    137                 m_maxValue = value;
    138                 Refresh();
    139             }
    140         }
    141 
    142         private int m_value = 0;
    143         /// <summary>
    144         /// 当前值
    145         /// </summary>
    146         [Description("当前值"), Category("自定义")]
    147         public int Value
    148         {
    149             get { return m_value; }
    150             set
    151             {
    152                 if (m_maxValue < value || value <= 0)
    153                     return;
    154                 m_value = value;
    155                 if (ValueChanged != null)
    156                 {
    157                     ValueChanged(this, null);
    158                 }
    159                 Refresh();
    160             }
    161         }
    162         private Font m_font = new Font("Arial Unicode MS", 20);
    163         [Description("文字字体"), Category("自定义")]
    164         public override Font Font
    165         {
    166             get
    167             {
    168                 return m_font;
    169             }
    170             set
    171             {
    172                 m_font = value;
    173                 Refresh();
    174             }
    175         }
    176         Color m_foreColor = Color.White;
    177         [Description("文字颜色"), Category("自定义")]
    178         public override Color ForeColor
    179         {
    180             get
    181             {
    182                 return m_foreColor;
    183             }
    184             set
    185             {
    186                 m_foreColor = value;
    187                 Refresh();
    188             }
    189         }
    190 
    191         private ShowType m_showType = ShowType.Ring;
    192 
    193         [Description("显示类型"), Category("自定义")]
    194         public ShowType ShowType
    195         {
    196             get { return m_showType; }
    197             set
    198             {
    199                 m_showType = value;
    200                 Refresh();
    201             }
    202         }
    203 
    204         public UCProcessEllipse()
    205         {
    206             InitializeComponent();
    207             this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    208             this.SetStyle(ControlStyles.DoubleBuffer, true);
    209             this.SetStyle(ControlStyles.ResizeRedraw, true);
    210             this.SetStyle(ControlStyles.Selectable, true);
    211             this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
    212             this.SetStyle(ControlStyles.UserPaint, true);
    213         }
    214 
    215         protected override void OnPaint(PaintEventArgs e)
    216         {
    217             base.OnPaint(e);
    218 
    219             var g = e.Graphics;
    220             g.SmoothingMode = SmoothingMode.AntiAlias;  //使绘图质量最高,即消除锯齿
    221             g.InterpolationMode = InterpolationMode.HighQualityBicubic;
    222             g.CompositingQuality = CompositingQuality.HighQuality;
    223 
    224             int intWidth = Math.Min(this.Size.Width, this.Size.Height);
    225             //底圆
    226             g.FillEllipse(new SolidBrush(m_backEllipseColor), new Rectangle(new Point(0, 0), new Size(intWidth, intWidth)));
    227             if (m_showType == HZH_Controls.Controls.ShowType.Ring)
    228             {
    229                 //中心圆
    230                 int intCore = intWidth - m_valueWidth * 2;
    231                 g.FillEllipse(new SolidBrush(m_coreEllipseColor), new Rectangle(new Point(m_valueWidth, m_valueWidth), new Size(intCore, intCore)));
    232                 //中心圆边框
    233                 if (m_isShowCoreEllipseBorder)
    234                 {
    235                     g.DrawEllipse(new Pen(m_valueColor, 2), new Rectangle(new Point(m_valueWidth + 1, m_valueWidth + 1), new Size(intCore - 1, intCore - 1)));
    236                 }
    237                 if (m_value > 0 && m_maxValue > 0)
    238                 {
    239                     float fltPercent = (float)m_value / (float)m_maxValue;
    240                     if (fltPercent > 1)
    241                     {
    242                         fltPercent = 1;
    243                     }
    244 
    245                     g.DrawArc(new Pen(m_valueColor, m_valueWidth - m_valueMargin * 2), new RectangleF(new Point(m_valueWidth / 2 + m_valueMargin / 4, m_valueWidth / 2 + m_valueMargin / 4), new SizeF(intWidth - m_valueWidth - m_valueMargin / 2 + (m_valueMargin == 0 ? 0 : 1), intWidth - m_valueWidth - m_valueMargin / 2 + (m_valueMargin == 0 ? 0 : 1))), -90, fltPercent * 360);
    246 
    247                     string strValueText = m_valueType == HZH_Controls.Controls.ValueType.Percent ? fltPercent.ToString("0%") : m_value.ToString();
    248                     System.Drawing.SizeF _txtSize = g.MeasureString(strValueText, this.Font);
    249                     g.DrawString(strValueText, this.Font, new SolidBrush(this.ForeColor), new PointF((intWidth - _txtSize.Width) / 2 + 1, (intWidth - _txtSize.Height) / 2 + 1));
    250                 }
    251             }
    252             else
    253             {
    254                 if (m_value > 0 && m_maxValue > 0)
    255                 {
    256                     float fltPercent = (float)m_value / (float)m_maxValue;
    257                     if (fltPercent > 1)
    258                     {
    259                         fltPercent = 1;
    260                     }
    261 
    262                     g.FillPie(new SolidBrush(m_valueColor), new Rectangle(m_valueMargin, m_valueMargin, intWidth - m_valueMargin * 2, intWidth - m_valueMargin * 2), -90, fltPercent * 360);
    263 
    264                     string strValueText = m_valueType == HZH_Controls.Controls.ValueType.Percent ? fltPercent.ToString("0%") : m_value.ToString();
    265                     System.Drawing.SizeF _txtSize = g.MeasureString(strValueText, this.Font);
    266                     g.DrawString(strValueText, this.Font, new SolidBrush(this.ForeColor), new PointF((intWidth - _txtSize.Width) / 2 + 1, (intWidth - _txtSize.Height) / 2 + 1));
    267                 }
    268             }
    269 
    270         }
    271     }
    272 
    273     public enum ValueType
    274     {
    275         /// <summary>
    276         /// 百分比
    277         /// </summary>
    278         Percent,
    279         /// <summary>
    280         /// 数值
    281         /// </summary>
    282         Absolute
    283     }
    284 
    285     public enum ShowType
    286     {
    287         /// <summary>
    288         /// 圆环
    289         /// </summary>
    290         Ring,
    291         /// <summary>
    292         /// 扇形
    293         /// </summary>
    294         Sector
    295     }
    296 }
    View Code
     1 namespace HZH_Controls.Controls
     2 {
     3     partial class UCProcessEllipse
     4     {
     5         /// <summary> 
     6         /// 必需的设计器变量。
     7         /// </summary>
     8         private System.ComponentModel.IContainer components = null;
     9 
    10         /// <summary> 
    11         /// 清理所有正在使用的资源。
    12         /// </summary>
    13         /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
    14         protected override void Dispose(bool disposing)
    15         {
    16             if (disposing && (components != null))
    17             {
    18                 components.Dispose();
    19             }
    20             base.Dispose(disposing);
    21         }
    22 
    23         #region 组件设计器生成的代码
    24 
    25         /// <summary> 
    26         /// 设计器支持所需的方法 - 不要
    27         /// 使用代码编辑器修改此方法的内容。
    28         /// </summary>
    29         private void InitializeComponent()
    30         {
    31             components = new System.ComponentModel.Container();
    32             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
    33         }
    34 
    35         #endregion
    36     }
    37 }
    View Code

    用处及效果

    最后的话

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

  • 相关阅读:
    【JZOJ3743】【BZOJ5158】Alice and Bob
    【JZOJ3719】K-D-Sequence
    【JZOJ1913】【BZOJ2124】等差子序列
    【JZOJ1914】【BZOJ2125】最短路
    【luoguP4768】【NOI2018】归程
    【JZOJ6435】【luoguP5666】【CSP-S2019】树的重心
    【JZOJ6434】【luoguP5665】【CSP-S2019】划分
    【JZOJ6433】【luoguP5664】【CSP-S2019】Emiya 家今天的饭
    【JZOJ6431】【luoguP5658】【CSP-S2019】括号树
    【JZOJ3673】【luoguP4040】【BZOJ3874】宅男计划
  • 原文地址:https://www.cnblogs.com/bfyx/p/11369691.html
Copyright © 2020-2023  润新知