• (四十六)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

    麻烦博客下方点个【推荐】,谢谢

    NuGet

    Install-Package HZH_Controls

    目录

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

    用处及效果

    准备工作

    这个用到GDI+画的,请先了解一下GDI+

    还有用到了基类控件UCControlBase来控制圆角和背景色,如果还不了解请移步查看

    (一)c#Winform自定义控件-基类控件

    另外用到了水波控件UCWave,如果不了解请移步查看

    (四十四)c#Winform自定义控件-水波

    开始

    添加一个用户控件UCProcessWave,继承UCControlBase

    一些属性

      1   private bool m_isRectangle = false;
      2         [Description("是否矩形"), Category("自定义")]
      3         public bool IsRectangle
      4         {
      5             get { return m_isRectangle; }
      6             set
      7             {
      8                 m_isRectangle = value;
      9                 if (value)
     10                 {
     11                     base.ConerRadius = 10;
     12                 }
     13                 else
     14                 {
     15                     base.ConerRadius = Math.Min(this.Width, this.Height);
     16                 }
     17             }
     18         }
     19         #region 不再使用的父类属性    English:Parent class attributes that are no longer used
     20         [Browsable(false)]
     21         public new int ConerRadius
     22         {
     23             get;
     24             set;
     25         }
     26         [Browsable(false)]
     27         public new bool IsRadius
     28         {
     29             get;
     30             set;
     31         }
     32 
     33         [Browsable(false)]
     34         public new Color FillColor
     35         {
     36             get;
     37             set;
     38         }
     39         #endregion
     40 
     41 
     42         [Description("值变更事件"), Category("自定义")]
     43         public event EventHandler ValueChanged;
     44         int m_value = 0;
     45         [Description("当前属性"), Category("自定义")]
     46         public int Value
     47         {
     48             set
     49             {
     50                 if (value > m_maxValue)
     51                     m_value = m_maxValue;
     52                 else if (value < 0)
     53                     m_value = 0;
     54                 else
     55                     m_value = value;
     56                 if (ValueChanged != null)
     57                     ValueChanged(this, null);
     58                 ucWave1.Height = (int)((double)m_value / (double)m_maxValue * this.Height) + ucWave1.WaveHeight;
     59                 Refresh();
     60             }
     61             get
     62             {
     63                 return m_value;
     64             }
     65         }
     66 
     67         private int m_maxValue = 100;
     68 
     69         [Description("最大值"), Category("自定义")]
     70         public int MaxValue
     71         {
     72             get { return m_maxValue; }
     73             set
     74             {
     75                 if (value < m_value)
     76                     m_maxValue = m_value;
     77                 else
     78                     m_maxValue = value;
     79                 Refresh();
     80             }
     81         }
     82 
     83         public override Font Font
     84         {
     85             get
     86             {
     87                 return base.Font;
     88             }
     89             set
     90             {
     91                 base.Font = value;
     92             }
     93         }
     94 
     95         public override Color ForeColor
     96         {
     97             get
     98             {
     99                 return base.ForeColor;
    100             }
    101             set
    102             {
    103                 base.ForeColor = value;
    104             }
    105         }
    106 
    107         [Description("值颜色"), Category("自定义")]
    108         public Color ValueColor
    109         {
    110             get { return this.ucWave1.WaveColor; }
    111             set
    112             {
    113                 this.ucWave1.WaveColor = value;
    114             }
    115         }
    116 
    117         [Description("边框宽度"), Category("自定义")]
    118         public override int RectWidth
    119         {
    120             get
    121             {
    122                 return base.RectWidth;
    123             }
    124             set
    125             {
    126                 if (value < 4)
    127                     base.RectWidth = 4;
    128                 else
    129                     base.RectWidth = value;
    130             }
    131         }

    构造函数一些设置

     1  public UCProcessWave()
     2         {
     3             InitializeComponent();
     4             this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
     5             this.SetStyle(ControlStyles.DoubleBuffer, true);
     6             this.SetStyle(ControlStyles.ResizeRedraw, true);
     7             this.SetStyle(ControlStyles.Selectable, true);
     8             this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
     9             this.SetStyle(ControlStyles.UserPaint, true);
    10             base.IsRadius = true;
    11             base.IsShowRect = false;
    12             RectWidth = 4;
    13             RectColor = Color.White;
    14             ucWave1.Height = (int)((double)m_value / (double)m_maxValue * this.Height) + ucWave1.WaveHeight;
    15             this.SizeChanged += UCProcessWave_SizeChanged;
    16             this.ucWave1.OnPainted += ucWave1_Painted;
    17             base.ConerRadius = Math.Min(this.Width, this.Height);
    18         }

    重绘

     1  protected override void OnPaint(PaintEventArgs e)
     2         {
     3             base.OnPaint(e);
     4             e.Graphics.SetGDIHigh();
     5             if (!m_isRectangle)
     6             {
     7                 //这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡
     8                 SolidBrush solidBrush = new SolidBrush(Color.White);
     9                 e.Graphics.DrawEllipse(new Pen(solidBrush, 2), new Rectangle(-1, -1, this.Width + 2, this.Height + 2));
    10             }
    11             string strValue = ((double)m_value / (double)m_maxValue).ToString("0.%");
    12             System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
    13             e.Graphics.DrawString(strValue, Font, new SolidBrush(ForeColor), new PointF((this.Width - sizeF.Width) / 2, (this.Height - sizeF.Height) / 2 + 1));
    14         }

    波形控件重绘时处理

     1   void ucWave1_Painted(object sender, PaintEventArgs e)
     2         {
     3             e.Graphics.SetGDIHigh();
     4             if (IsShowRect)
     5             {
     6                 if (m_isRectangle)
     7                 {
     8                     Color rectColor = RectColor;
     9                     Pen pen = new Pen(rectColor, (float)RectWidth);
    10                     Rectangle clientRectangle = new Rectangle(0, this.ucWave1.Height - this.Height, this.Width, this.Height);
    11                     GraphicsPath graphicsPath = new GraphicsPath();
    12                     graphicsPath.AddArc(clientRectangle.X, clientRectangle.Y, 10, 10, 180f, 90f);
    13                     graphicsPath.AddArc(clientRectangle.Width - 10 - 1, clientRectangle.Y, 10, 10, 270f, 90f);
    14                     graphicsPath.AddArc(clientRectangle.Width - 10 - 1, clientRectangle.Bottom - 10 - 1, 10, 10, 0f, 90f);
    15                     graphicsPath.AddArc(clientRectangle.X, clientRectangle.Bottom - 10 - 1, 10, 10, 90f, 90f);
    16                     graphicsPath.CloseFigure();
    17                     e.Graphics.DrawPath(pen, graphicsPath);
    18                 }
    19                 else
    20                 {
    21                     SolidBrush solidBrush = new SolidBrush(RectColor);
    22                     e.Graphics.DrawEllipse(new Pen(solidBrush, RectWidth), new Rectangle(0, this.ucWave1.Height - this.Height, this.Width, this.Height));
    23                 }
    24             }
    25 
    26             if (!m_isRectangle)
    27             {
    28                 //这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡
    29                 SolidBrush solidBrush1 = new SolidBrush(Color.White);
    30                 e.Graphics.DrawEllipse(new Pen(solidBrush1, 2), new Rectangle(-1, this.ucWave1.Height - this.Height - 1, this.Width + 2, this.Height + 2));
    31             }
    32             string strValue = ((double)m_value / (double)m_maxValue).ToString("0.%");
    33             System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
    34             e.Graphics.DrawString(strValue, Font, new SolidBrush(ForeColor), new PointF((this.Width - sizeF.Width) / 2, (this.ucWave1.Height - this.Height) + (this.Height - sizeF.Height) / 2));
    35         }

    不知道你们有没有注意这句话

     //这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡

    因为设置原价导致了区域毛边,所有画个没有毛边的边框覆盖之

    完整代码

      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 UCProcessWave : UCControlBase
     14     {
     15         private bool m_isRectangle = false;
     16         [Description("是否矩形"), Category("自定义")]
     17         public bool IsRectangle
     18         {
     19             get { return m_isRectangle; }
     20             set
     21             {
     22                 m_isRectangle = value;
     23                 if (value)
     24                 {
     25                     base.ConerRadius = 10;
     26                 }
     27                 else
     28                 {
     29                     base.ConerRadius = Math.Min(this.Width, this.Height);
     30                 }
     31             }
     32         }
     33         #region 不再使用的父类属性    English:Parent class attributes that are no longer used
     34         [Browsable(false)]
     35         public new int ConerRadius
     36         {
     37             get;
     38             set;
     39         }
     40         [Browsable(false)]
     41         public new bool IsRadius
     42         {
     43             get;
     44             set;
     45         }
     46 
     47         [Browsable(false)]
     48         public new Color FillColor
     49         {
     50             get;
     51             set;
     52         }
     53         #endregion
     54 
     55 
     56         [Description("值变更事件"), Category("自定义")]
     57         public event EventHandler ValueChanged;
     58         int m_value = 0;
     59         [Description("当前属性"), Category("自定义")]
     60         public int Value
     61         {
     62             set
     63             {
     64                 if (value > m_maxValue)
     65                     m_value = m_maxValue;
     66                 else if (value < 0)
     67                     m_value = 0;
     68                 else
     69                     m_value = value;
     70                 if (ValueChanged != null)
     71                     ValueChanged(this, null);
     72                 ucWave1.Height = (int)((double)m_value / (double)m_maxValue * this.Height) + ucWave1.WaveHeight;
     73                 Refresh();
     74             }
     75             get
     76             {
     77                 return m_value;
     78             }
     79         }
     80 
     81         private int m_maxValue = 100;
     82 
     83         [Description("最大值"), Category("自定义")]
     84         public int MaxValue
     85         {
     86             get { return m_maxValue; }
     87             set
     88             {
     89                 if (value < m_value)
     90                     m_maxValue = m_value;
     91                 else
     92                     m_maxValue = value;
     93                 Refresh();
     94             }
     95         }
     96 
     97         public override Font Font
     98         {
     99             get
    100             {
    101                 return base.Font;
    102             }
    103             set
    104             {
    105                 base.Font = value;
    106             }
    107         }
    108 
    109         public override Color ForeColor
    110         {
    111             get
    112             {
    113                 return base.ForeColor;
    114             }
    115             set
    116             {
    117                 base.ForeColor = value;
    118             }
    119         }
    120 
    121         [Description("值颜色"), Category("自定义")]
    122         public Color ValueColor
    123         {
    124             get { return this.ucWave1.WaveColor; }
    125             set
    126             {
    127                 this.ucWave1.WaveColor = value;
    128             }
    129         }
    130 
    131         [Description("边框宽度"), Category("自定义")]
    132         public override int RectWidth
    133         {
    134             get
    135             {
    136                 return base.RectWidth;
    137             }
    138             set
    139             {
    140                 if (value < 4)
    141                     base.RectWidth = 4;
    142                 else
    143                     base.RectWidth = value;
    144             }
    145         }
    146 
    147         public UCProcessWave()
    148         {
    149             InitializeComponent();
    150             this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
    151             this.SetStyle(ControlStyles.DoubleBuffer, true);
    152             this.SetStyle(ControlStyles.ResizeRedraw, true);
    153             this.SetStyle(ControlStyles.Selectable, true);
    154             this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
    155             this.SetStyle(ControlStyles.UserPaint, true);
    156             base.IsRadius = true;
    157             base.IsShowRect = false;
    158             RectWidth = 4;
    159             RectColor = Color.White;
    160             ucWave1.Height = (int)((double)m_value / (double)m_maxValue * this.Height) + ucWave1.WaveHeight;
    161             this.SizeChanged += UCProcessWave_SizeChanged;
    162             this.ucWave1.OnPainted += ucWave1_Painted;
    163             base.ConerRadius = Math.Min(this.Width, this.Height);
    164         }
    165 
    166         void ucWave1_Painted(object sender, PaintEventArgs e)
    167         {
    168             e.Graphics.SetGDIHigh();
    169             if (IsShowRect)
    170             {
    171                 if (m_isRectangle)
    172                 {
    173                     Color rectColor = RectColor;
    174                     Pen pen = new Pen(rectColor, (float)RectWidth);
    175                     Rectangle clientRectangle = new Rectangle(0, this.ucWave1.Height - this.Height, this.Width, this.Height);
    176                     GraphicsPath graphicsPath = new GraphicsPath();
    177                     graphicsPath.AddArc(clientRectangle.X, clientRectangle.Y, 10, 10, 180f, 90f);
    178                     graphicsPath.AddArc(clientRectangle.Width - 10 - 1, clientRectangle.Y, 10, 10, 270f, 90f);
    179                     graphicsPath.AddArc(clientRectangle.Width - 10 - 1, clientRectangle.Bottom - 10 - 1, 10, 10, 0f, 90f);
    180                     graphicsPath.AddArc(clientRectangle.X, clientRectangle.Bottom - 10 - 1, 10, 10, 90f, 90f);
    181                     graphicsPath.CloseFigure();
    182                     e.Graphics.DrawPath(pen, graphicsPath);
    183                 }
    184                 else
    185                 {
    186                     SolidBrush solidBrush = new SolidBrush(RectColor);
    187                     e.Graphics.DrawEllipse(new Pen(solidBrush, RectWidth), new Rectangle(0, this.ucWave1.Height - this.Height, this.Width, this.Height));
    188                 }
    189             }
    190 
    191             if (!m_isRectangle)
    192             {
    193                 //这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡
    194                 SolidBrush solidBrush1 = new SolidBrush(Color.White);
    195                 e.Graphics.DrawEllipse(new Pen(solidBrush1, 2), new Rectangle(-1, this.ucWave1.Height - this.Height - 1, this.Width + 2, this.Height + 2));
    196             }
    197             string strValue = ((double)m_value / (double)m_maxValue).ToString("0.%");
    198             System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
    199             e.Graphics.DrawString(strValue, Font, new SolidBrush(ForeColor), new PointF((this.Width - sizeF.Width) / 2, (this.ucWave1.Height - this.Height) + (this.Height - sizeF.Height) / 2));
    200         }
    201 
    202         void UCProcessWave_SizeChanged(object sender, EventArgs e)
    203         {
    204             if (!m_isRectangle)
    205             {
    206                 base.ConerRadius = Math.Min(this.Width, this.Height);
    207                 if (this.Width != this.Height)
    208                 {
    209                     this.Size = new Size(Math.Min(this.Width, this.Height), Math.Min(this.Width, this.Height));
    210                 }
    211             }
    212         }
    213 
    214         protected override void OnPaint(PaintEventArgs e)
    215         {
    216             base.OnPaint(e);
    217             e.Graphics.SetGDIHigh();
    218             if (!m_isRectangle)
    219             {
    220                 //这里曲线救国,因为设置了控件区域导致的毛边,通过画一个没有毛边的圆遮挡
    221                 SolidBrush solidBrush = new SolidBrush(Color.White);
    222                 e.Graphics.DrawEllipse(new Pen(solidBrush, 2), new Rectangle(-1, -1, this.Width + 2, this.Height + 2));
    223             }
    224             string strValue = ((double)m_value / (double)m_maxValue).ToString("0.%");
    225             System.Drawing.SizeF sizeF = e.Graphics.MeasureString(strValue, Font);
    226             e.Graphics.DrawString(strValue, Font, new SolidBrush(ForeColor), new PointF((this.Width - sizeF.Width) / 2, (this.Height - sizeF.Height) / 2 + 1));
    227         }
    228     }
    229 }
    View Code
     1 namespace HZH_Controls.Controls
     2 {
     3     partial class UCProcessWave
     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             this.ucWave1 = new HZH_Controls.Controls.UCWave();
    32             this.SuspendLayout();
    33             // 
    34             // ucWave1
    35             // 
    36             this.ucWave1.Dock = System.Windows.Forms.DockStyle.Bottom;
    37             this.ucWave1.Location = new System.Drawing.Point(0, 140);
    38             this.ucWave1.Name = "ucWave1";
    39             this.ucWave1.Size = new System.Drawing.Size(150, 10);
    40             this.ucWave1.TabIndex = 0;
    41             this.ucWave1.Text = "ucWave1";
    42             this.ucWave1.WaveColor = System.Drawing.Color.FromArgb(((int)(((byte)(73)))), ((int)(((byte)(119)))), ((int)(((byte)(232)))));
    43             this.ucWave1.WaveHeight = 15;
    44             this.ucWave1.WaveSleep = 100;
    45             this.ucWave1.WaveWidth = 100;
    46             // 
    47             // UCProcessWave
    48             // 
    49             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
    50             this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(197)))), ((int)(((byte)(229)))), ((int)(((byte)(250)))));
    51             this.Controls.Add(this.ucWave1);
    52             this.Name = "UCProcessWave";
    53             this.Size = new System.Drawing.Size(150, 150);
    54             this.ResumeLayout(false);
    55 
    56         }
    57 
    58         #endregion
    59 
    60         private UCWave ucWave1;
    61     }
    62 }
    View Code

    最后的话

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

  • 相关阅读:
    安卓目录分析——MainActivity.java和activity_main.xml
    安卓目录理解 —— AndroidMainifest.xml
    安卓教程列表
    安卓目录介绍
    ideal 安卓环境搭建
    ideal 2019激活 方法
    binding.gyp not found 安装java npm 报错
    vue-cli脚手架打包页面空白
    .java文件转为.class文件转jar包
    前端框架Vue自学之Vue基础语法(二)
  • 原文地址:https://www.cnblogs.com/bfyx/p/11399183.html
Copyright © 2020-2023  润新知