前提

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

开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control
<https://gitee.com/kwwwvagaa/net_winform_custom_control>

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

欢迎前来交流探讨: 企鹅群568015492  <https://shang.qq.com/wpa/qunwpa?
idkey=6e08741ef16fe53bf0314c1c9e336c4f626047943a8b76bac062361bab6b4f8d>

NuGet
Install-Package HZH_Controls
目录

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

准备工作

前面写过一个进度条,但是并不是太好,这次用GDI+再重绘一个,不了解GDI+的自行百度了解下先

(七)c#Winform自定义控件-进度条 <https://www.cnblogs.com/bfyx/p/11362258.html>

开始

添加一个类,命名UCProcessLine,继承Control

添加一个枚举,用以如何显示值
1 public enum ValueTextType 2 { 3 None, 4 /// <summary> 5 /// 百分比 6 ///
</summary> 7 Percent, 8 /// <summary> 9 /// 数值 10 /// </summary> 11
Absolute12 }
 

添加一些属性
1 [Description("值变更事件"), Category("自定义")] 2 public event EventHandler
ValueChanged; 3 int m_value = 0; 4 [Description("当前属性"), Category("自定义")] 5
public int Value 6 { 7 set 8 { 9 if (value > m_maxValue) 10 m_value =
m_maxValue; 11 else if (value < 0) 12 m_value = 0; 13 else 14 m_value =
value; 15 if (ValueChanged != null) 16 ValueChanged(this, null); 17
Refresh(); 18 } 19 get 20 { 21 return m_value; 22 } 23 } 24 25
private int m_maxValue = 100; 26 27 [Description("最大值"), Category("自定义")] 28
public int MaxValue 29 { 30 get { return m_maxValue; } 31 set 32 { 33 if
(value < m_value) 34 m_maxValue = m_value; 35 else 36 m_maxValue = value; 37
Refresh(); 38 } 39 } 40 41 Color m_valueColor = Color.FromArgb(73, 119,
232); 42 43 [Description("值进度条颜色"), Category("自定义")] 44 public Color
ValueColor 45 { 46 get { return m_valueColor; } 47 set 48 { 49
m_valueColor = value; 50 Refresh(); 51 } 52 } 53 54 private Color
m_valueBGColor = Color.White; 55 56 [Description("值背景色"), Category("自定义")] 57
public Color ValueBGColor 58 { 59 get { return m_valueBGColor; } 60 set 61
{ 62 m_valueBGColor = value; 63 Refresh(); 64 } 65 } 66 67 private
Color m_borderColor = Color.FromArgb(192, 192, 192); 68 69 [Description("边框颜色"
), Category("自定义")] 70 public Color BorderColor 71 { 72 get { return
m_borderColor; } 73 set 74 { 75 m_borderColor = value; 76 Refresh(); 77 }
78 } 79 80 [Description("值字体"), Category("自定义")] 81 public override Font
Font 82 { 83 get 84 { 85 return base.Font; 86 } 87 set 88 { 89 base
.Font = value; 90 Refresh(); 91 } 92 } 93 94 [Description("值字体颜色"),
Category("自定义")] 95 public override System.Drawing.Color ForeColor 96 { 97
get 98 { 99 return base.ForeColor; 100 } 101 set 102 { 103 base.ForeColor =
value;104 Refresh(); 105 } 106 } 107 private ValueTextType m_valueTextType =
ValueTextType.Percent;108 109 [Description("值显示样式"), Category("自定义")] 110
public ValueTextType ValueTextType 111 { 112 get { return m_valueTextType; }
113 set 114 { 115 m_valueTextType = value; 116 Refresh(); 117 } 118 }
重绘
1 protected override void OnPaint(PaintEventArgs e) 2 { 3
Console.WriteLine(DateTime.Now); 4 base.OnPaint(e); 5 Graphics g = e.Graphics;
6 g.SetGDIHigh(); 7 8 Brush sb = new SolidBrush(m_valueBGColor); 9
g.FillRectangle(sb,new Rectangle(base.ClientRectangle.X, base.ClientRectangle.Y,
base.ClientRectangle.Width - 3, base.ClientRectangle.Height - 2)); 10
GraphicsPath path1 = ControlHelper.CreateRoundedRectanglePath(new Rectangle(base
.ClientRectangle.X,base.ClientRectangle.Y + 1, base.ClientRectangle.Width - 3,
base.ClientRectangle.Height - 4), 3); 11 g.DrawPath(new Pen(m_borderColor, 1),
path1);12 LinearGradientBrush lgb = new LinearGradientBrush(new Point(0, 0), new
Point(0, base.ClientRectangle.Height - 3), m_valueColor, Color.FromArgb(200,
m_valueColor.R, m_valueColor.G, m_valueColor.B));13 g.FillPath(lgb,
ControlHelper.CreateRoundedRectanglePath(new Rectangle(0, (base
.ClientRectangle.Height - (base.ClientRectangle.Height - 3)) / 2, (base
.ClientRectangle.Width -3) * Value / m_maxValue, base.ClientRectangle.Height - 4
),3)); 14 string strValue = string.Empty; 15 if (m_valueTextType ==
HZH_Controls.Controls.ValueTextType.Percent)16 strValue = ((float)Value / (float
)m_maxValue).ToString("0%"); 17 else if (m_valueTextType ==
HZH_Controls.Controls.ValueTextType.Absolute)18 strValue = Value + "/" +
m_maxValue;19 if (!string.IsNullOrEmpty(strValue)) 20 { 21
System.Drawing.SizeF sizeF = g.MeasureString(strValue, Font); 22
g.DrawString(strValue, Font,new SolidBrush(ForeColor), new PointF((this.Width -
sizeF.Width) /2, (this.Height - sizeF.Height) / 2 + 1)); 23 } 24 }
完整代码来一份
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 class UCProcessLine : Control 14 { 15 [Description("值变更事件"), Category(
"自定义")] 16 public event EventHandler ValueChanged; 17 int m_value = 0; 18
[Description("当前属性"), Category("自定义")] 19 public int Value 20 { 21 set 22
{ 23 if (value > m_maxValue) 24 m_value = m_maxValue; 25 else if (value < 0)
26 m_value = 0; 27 else 28 m_value = value; 29 if (ValueChanged != null) 30
ValueChanged(this, null); 31 Refresh(); 32 } 33 get 34 { 35 return
m_value; 36 } 37 } 38 39 private int m_maxValue = 100; 40 41
[Description("最大值"), Category("自定义")] 42 public int MaxValue 43 { 44 get {
return m_maxValue; } 45 set 46 { 47 if (value < m_value) 48 m_maxValue =
m_value; 49 else 50 m_maxValue = value; 51 Refresh(); 52 } 53 } 54 55
Color m_valueColor = Color.FromArgb(73, 119, 232); 56 57 [Description("值进度条颜色"
), Category("自定义")] 58 public Color ValueColor 59 { 60 get { return
m_valueColor; } 61 set 62 { 63 m_valueColor = value; 64 Refresh(); 65 }
66 } 67 68 private Color m_valueBGColor = Color.White; 69 70 [Description("
值背景色"), Category("自定义")] 71 public Color ValueBGColor 72 { 73 get { return
m_valueBGColor; } 74 set 75 { 76 m_valueBGColor = value; 77 Refresh(); 78
} 79 } 80 81 private Color m_borderColor = Color.FromArgb(192, 192, 192);
82 83 [Description("边框颜色"), Category("自定义")] 84 public Color BorderColor 85
{ 86 get { return m_borderColor; } 87 set 88 { 89 m_borderColor = value; 90
Refresh(); 91 } 92 } 93 94 [Description("值字体"), Category("自定义")] 95
public override Font Font 96 { 97 get 98 { 99 return base.Font; 100 } 101
set 102 { 103 base.Font = value; 104 Refresh(); 105 } 106 } 107 108
[Description("值字体颜色"), Category("自定义")] 109 public override
System.Drawing.Color ForeColor110 { 111 get 112 { 113 return base.ForeColor;
114 } 115 set 116 { 117 base.ForeColor = value; 118 Refresh(); 119 } 120 }
121 private ValueTextType m_valueTextType = ValueTextType.Percent; 122 123
[Description("值显示样式"), Category("自定义")] 124 public ValueTextType ValueTextType
125 { 126 get { return m_valueTextType; } 127 set 128 { 129 m_valueTextType =
value;130 Refresh(); 131 } 132 } 133 public UCProcessLine() 134 { 135 Size =
new Size(200, 15); 136 ForeColor = Color.FromArgb(255, 77, 59); 137 Font = new
Font("Arial Unicode MS", 10); 138 this
.SetStyle(ControlStyles.AllPaintingInWmPaint,true); 139 this
.SetStyle(ControlStyles.DoubleBuffer,true); 140 this
.SetStyle(ControlStyles.ResizeRedraw,true); 141 this
.SetStyle(ControlStyles.Selectable,true); 142 this
.SetStyle(ControlStyles.SupportsTransparentBackColor,true); 143 this
.SetStyle(ControlStyles.UserPaint,true); 144 } 145 146 protected override void
OnPaint(PaintEventArgs e)147 { 148 Console.WriteLine(DateTime.Now); 149 base
.OnPaint(e);150 Graphics g = e.Graphics; 151 g.SetGDIHigh(); 152 153 Brush sb =
new SolidBrush(m_valueBGColor); 154 g.FillRectangle(sb, new Rectangle(base
.ClientRectangle.X,base.ClientRectangle.Y, base.ClientRectangle.Width - 3, base
.ClientRectangle.Height -2)); 155 GraphicsPath path1 =
ControlHelper.CreateRoundedRectanglePath(new Rectangle(base.ClientRectangle.X,
base.ClientRectangle.Y + 1, base.ClientRectangle.Width - 3, base
.ClientRectangle.Height -4), 3); 156 g.DrawPath(new Pen(m_borderColor, 1),
path1);157 LinearGradientBrush lgb = new LinearGradientBrush(new Point(0, 0),
new Point(0, base.ClientRectangle.Height - 3), m_valueColor, Color.FromArgb(200
, m_valueColor.R, m_valueColor.G, m_valueColor.B));158 g.FillPath(lgb,
ControlHelper.CreateRoundedRectanglePath(new Rectangle(0, (base
.ClientRectangle.Height - (base.ClientRectangle.Height - 3)) / 2, (base
.ClientRectangle.Width -3) * Value / m_maxValue, base.ClientRectangle.Height - 4
),3)); 159 string strValue = string.Empty; 160 if (m_valueTextType ==
HZH_Controls.Controls.ValueTextType.Percent)161 strValue = ((float)Value / (
float)m_maxValue).ToString("0%"); 162 else if (m_valueTextType ==
HZH_Controls.Controls.ValueTextType.Absolute)163 strValue = Value + "/" +
m_maxValue;164 if (!string.IsNullOrEmpty(strValue)) 165 { 166
System.Drawing.SizeF sizeF = g.MeasureString(strValue, Font); 167
g.DrawString(strValue, Font,new SolidBrush(ForeColor), new PointF((this.Width -
sizeF.Width) /2, (this.Height - sizeF.Height) / 2 + 1)); 168 } 169 } 170 171
}172 173 public enum ValueTextType 174 { 175 None, 176 /// <summary> 177 ///
百分比178 /// </summary> 179 Percent, 180 /// <summary> 181 /// 数值 182 ///
</summary> 183 Absolute 184 } 185 } View Code
 

用处及效果



最后的话

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