前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl 
<https://github.com/kwwwvagaa/NetWinformControl>
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git 
<https://gitee.com/kwwwvagaa/net_winform_custom_control.git>
如果觉得写的还行,请点个 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+画的,不了解自行百度学习下
第二个有提示文字的用到了(五十一)c#Winform自定义控件-文字提示 
<https://www.cnblogs.com/bfyx/p/11430049.html>
开始
添加一个类UCTrackBar,继承Control
添加属性
 1 [Description("值改变事件"), Category("自定义")]  2 public event EventHandler 
ValueChanged; 3  4 private int dcimalDigits = 0;  5  6 [Description("值小数精确位数"), 
Category("自定义")]  7 public int DcimalDigits  8  {  9 get { return dcimalDigits; 
}10 set { dcimalDigits = value; } 11  } 12 13 private float lineWidth = 10; 14 
15 [Description("线宽度"), Category("自定义")] 16 public float LineWidth 17  { 18 get 
{return lineWidth; } 19 set { lineWidth = value; } 20  } 21 22 private float 
minValue =0; 23 24 [Description("最小值"), Category("自定义")] 25 public float 
MinValue26  { 27 get { return minValue; } 28 set 29  { 30 if (minValue > 
m_value)31 return; 32 minValue = value; 33 this.Refresh(); 34  } 35  } 36 37 
private float maxValue = 100; 38 39 [Description("最大值"), Category("自定义")] 40 
public float MaxValue 41  { 42 get { return maxValue; } 43 set 44  { 45 if 
(value < m_value) 46 return; 47 maxValue = value; 48 this.Refresh(); 49  } 50  }
51 52 private float m_value = 0; 53 54 [Description("值"), Category("自定义")] 55 
public float Value 56  { 57 get { return this.m_value; } 58 set 59  { 60 if 
(value > maxValue || value < minValue) 61 return; 62 var v = (float)Math.Round((
double)value, dcimalDigits); 63 if (value == v) 64 return; 65 this.m_value = v; 
66 this.Refresh(); 67 if (ValueChanged != null) 68  { 69 ValueChanged(this, null
);70  } 71  } 72  } 73 74 private Color m_lineColor = Color.FromArgb(255, 77, 59
);75 76 [Description("线颜色"), Category("自定义")] 77 public Color LineColor 78  { 79
get { return m_lineColor; } 80 set 81  { 82 m_lineColor = value; 83 this
.Refresh();84  } 85  } 86  RectangleF m_lineRectangle; 87 RectangleF 
m_trackRectangle; 
重绘
 1 protected override void OnPaint(PaintEventArgs e)  2  {  3 base.OnPaint(e); 
 4 Graphics g = e.Graphics;  5  g.SetGDIHigh();  6 m_lineRectangle = new 
RectangleF(lineWidth, (this.Size.Height - lineWidth) / 2, this.Size.Width - 
lineWidth *2, lineWidth);  7 GraphicsPath pathLine = 
ControlHelper.CreateRoundedRectanglePath(m_lineRectangle,5);  8 g.FillPath(new 
SolidBrush(m_lineColor), pathLine); 9 m_trackRectangle = new 
RectangleF(m_lineRectangle.Left - lineWidth + (((float)m_value / (float
)(maxValue - minValue)) * (this.Size.Width - lineWidth * 2)), (this.Size.Height 
- lineWidth *2) / 2, lineWidth * 2, lineWidth * 2); 10 g.FillEllipse(new 
SolidBrush(m_lineColor), m_trackRectangle);11 g.FillEllipse(Brushes.White, new 
RectangleF(m_trackRectangle.X + m_trackRectangle.Width /4, m_trackRectangle.Y + 
m_trackRectangle.Height /4, m_trackRectangle.Width / 2, m_trackRectangle.Height 
/2)); 12 } 
处理拖动
 1 public UCTrackBar()  2  {  3 this.Size = new Size(250, 30);  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 this.MouseDown += 
UCTrackBar_MouseDown;11 this.MouseMove += UCTrackBar_MouseMove; 12 this.MouseUp 
+= UCTrackBar_MouseUp; 13  } 14 15 bool blnDown = false; 16 void 
UCTrackBar_MouseDown(object sender, MouseEventArgs e) 17  { 18 if 
(m_lineRectangle.Contains(e.Location) || m_trackRectangle.Contains(e.Location)) 
19  { 20 blnDown = true; 21 Value = ((float)e.Location.X / (float)this.Width) * 
(maxValue - minValue); 22  } 23  } 24 void UCTrackBar_MouseMove(object sender, 
MouseEventArgs e)25  { 26 if (blnDown) 27  { 28 Value = ((float)e.Location.X / (
float)this.Width) * (maxValue - minValue); 29  } 30  } 31 void 
UCTrackBar_MouseUp(object sender, MouseEventArgs e) 32  { 33 blnDown = false; 34
 } 
完整代码
 1 using System;  2 using System.Collections.Generic;  3 using System.Linq;  4 
using System.Text;  5 using System.Windows.Forms;  6 using System.Drawing;  7 
using System.Drawing.Drawing2D;  8 using System.ComponentModel;  9  10 namespace
 HZH_Controls.Controls 11 {  12 public class UCTrackBar : Control  13  {  14 
[Description("值改变事件"), Category("自定义")]  15 public event EventHandler 
ValueChanged; 16  17 private int dcimalDigits = 0;  18  19 [Description("值小数精确位数
"), Category("自定义")]  20 public int DcimalDigits  21  {  22 get { return 
dcimalDigits; } 23 set { dcimalDigits = value; }  24  }  25  26 private float 
lineWidth =10;  27  28 [Description("线宽度"), Category("自定义")]  29 public float 
LineWidth 30  {  31 get { return lineWidth; }  32 set { lineWidth = value; }  33
 } 34  35 private float minValue = 0;  36  37 [Description("最小值"), Category("自定义
")]  38 public float MinValue  39  {  40 get { return minValue; }  41 set  42  {
 43 if (minValue > m_value)  44 return;  45 minValue = value;  46 this
.Refresh(); 47  }  48  }  49  50 private float maxValue = 100;  51  52 
[Description("最大值"), Category("自定义")]  53 public float MaxValue  54  {  55 get {
return maxValue; }  56 set  57  {  58 if (value < m_value)  59 return;  60 
maxValue = value;  61 this.Refresh();  62  }  63  }  64  65 private float 
m_value =0;  66  67 [Description("值"), Category("自定义")]  68 public float Value  
69  {  70 get { return this.m_value; }  71 set  72  {  73 if (value > maxValue 
|| value < minValue)  74 return;  75 var v = (float)Math.Round((double)value, 
dcimalDigits); 76 if (value == v)  77 return;  78 this.m_value = v;  79 this
.Refresh(); 80 if (ValueChanged != null)  81  {  82 ValueChanged(this, null);  
83  }  84  }  85  }  86  87 private Color m_lineColor = Color.FromArgb(255, 77, 
59);  88  89 [Description("线颜色"), Category("自定义")]  90 public Color LineColor  
91  {  92 get { return m_lineColor; }  93 set  94  {  95 m_lineColor = value;  
96 this.Refresh();  97  }  98  }  99  RectangleF m_lineRectangle; 100  
RectangleF m_trackRectangle;101 102 public UCTrackBar() 103  { 104 this.Size = 
new Size(250, 30); 105 this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
106 this.SetStyle(ControlStyles.DoubleBuffer, true); 107 this
.SetStyle(ControlStyles.ResizeRedraw,true); 108 this
.SetStyle(ControlStyles.Selectable,true); 109 this
.SetStyle(ControlStyles.SupportsTransparentBackColor,true); 110 this
.SetStyle(ControlStyles.UserPaint,true); 111 this.MouseDown += 
UCTrackBar_MouseDown;112 this.MouseMove += UCTrackBar_MouseMove; 113 this
.MouseUp += UCTrackBar_MouseUp; 114  } 115 116 bool blnDown = false; 117 void 
UCTrackBar_MouseDown(object sender, MouseEventArgs e) 118  { 119 if 
(m_lineRectangle.Contains(e.Location) || m_trackRectangle.Contains(e.Location)) 
120  { 121 blnDown = true; 122 Value = ((float)e.Location.X / (float)this
.Width) * (maxValue - minValue); 123  } 124  } 125 void UCTrackBar_MouseMove(
object sender, MouseEventArgs e) 126  { 127 if (blnDown) 128  { 129 Value = ((
float)e.Location.X / (float)this.Width) * (maxValue - minValue); 130  } 131  } 
132 void UCTrackBar_MouseUp(object sender, MouseEventArgs e) 133  { 134 blnDown 
=false; 135  } 136 137 138 protected override void OnPaint(PaintEventArgs e) 139
 {140 base.OnPaint(e); 141 Graphics g = e.Graphics; 142  g.SetGDIHigh(); 143 
m_lineRectangle =new RectangleF(lineWidth, (this.Size.Height - lineWidth) / 2, 
this.Size.Width - lineWidth * 2, lineWidth); 144 GraphicsPath pathLine = 
ControlHelper.CreateRoundedRectanglePath(m_lineRectangle,5); 145 g.FillPath(new 
SolidBrush(m_lineColor), pathLine);146 m_trackRectangle = new 
RectangleF(m_lineRectangle.Left - lineWidth + (((float)m_value / (float
)(maxValue - minValue)) * (this.Size.Width - lineWidth * 2)), (this.Size.Height 
- lineWidth *2) / 2, lineWidth * 2, lineWidth * 2); 147 g.FillEllipse(new 
SolidBrush(m_lineColor), m_trackRectangle);148 g.FillEllipse(Brushes.White, new 
RectangleF(m_trackRectangle.X + m_trackRectangle.Width /4, m_trackRectangle.Y + 
m_trackRectangle.Height /4, m_trackRectangle.Width / 2, m_trackRectangle.Height 
/2)); 149  } 150  } 151 } View Code 
 
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 
<https://gitee.com/kwwwvagaa/net_winform_custom_control> 点个星星吧
热门工具 换一换
