官网
前提
入行已经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+的自行百度了解下先
开始
添加一个类,命名UCProcessLine,继承Control
添加一个枚举,用以如何显示值
1 public enum ValueTextType 2 { 3 None, 4 /// <summary> 5 /// 百分比 6 /// </summary> 7 Percent, 8 /// <summary> 9 /// 数值 10 /// </summary> 11 Absolute 12 }
添加一些属性
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 ForeColor 110 { 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 }
用处及效果
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星 星吧