(四十六)c#Winform自定义控件-水波进度条
Posted bfyx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(四十六)c#Winform自定义控件-水波进度条相关的知识,希望对你有一定的参考价值。
前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
麻烦博客下方点个【推荐】,谢谢
NuGet
Install-Package HZH_Controls
目录
https://www.cnblogs.com/bfyx/p/11364884.html
用处及效果
准备工作
这个用到GDI+画的,请先了解一下GDI+
还有用到了基类控件UCControlBase来控制圆角和背景色,如果还不了解请移步查看
另外用到了水波控件UCWave,如果不了解请移步查看
开始
添加一个用户控件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
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
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧
以上是关于(四十六)c#Winform自定义控件-水波进度条的主要内容,如果未能解决你的问题,请参考以下文章