using System; using System.Windows.Forms; using System.Drawing; using System.ComponentModel; namespace PaintDotNet.CustomControl { public partial class UCTrackBar : Control { [Description("Left值改变事件"), Category("自定义")] public event EventHandler Value1Changed; [Description("Center值改变事件"), Category("自定义")] public event EventHandler Value2Changed; [Description("Right值改变事件"), Category("自定义")] public event EventHandler Value3Changed; [Description("鼠标抬起事件"), Category("自定义")] public event EventHandler ValueMouseUp; private int dcimalDigits = 0; [Description("值小数精确位数"), Category("自定义")] public int DcimalDigits { get { return dcimalDigits; } set { dcimalDigits = value; } } private float lineWidth = 10; [Description("线宽度"), Category("自定义")] public float LineWidth { get { return lineWidth; } set { lineWidth = value; } } private float minValue = 0; [Description("最小值"), Category("自定义")] public float MinValue { get { return minValue; } set { if (minValue > m1_value) return; if (minValue > m2_value) return; if (minValue > m3_value) return; minValue = value; this.Refresh(); } } private float maxValue = 255;//256; [Description("最大值"), Category("自定义")] public float MaxValue { get { return maxValue; } set { if (value < m1_value) return; if (value < m2_value) return; if (value < m3_value) return; maxValue = value; this.Refresh(); } } private float m1_value = 0;//2;//0; private float m2_value = 127;//128; private float m3_value = 255;//254;//256; [Description("Left值"), Category("自定义")] public float Value1 { get { return this.m1_value; } set { if (value > maxValue || value < minValue) return; var v = (float)Math.Round((double)value, dcimalDigits); if (this.m1_value == v) return; this.m1_value = v; } } [Description("Center值"), Category("自定义")] public float Value2 { get { return this.m2_value; } set { if (value > maxValue || value < minValue) return; var v = (float)Math.Round((double)value, dcimalDigits); if (this.m2_value == v) return; this.m2_value = v; //this.Refresh(); //if (Value2Changed != null) //{ // Value2Changed(this, null); //} } } [Description("Right值"), Category("自定义")] public float Value3 { get { return this.m3_value; } set { if (value > maxValue || value < minValue) return; var v = (float)Math.Round((double)value, dcimalDigits); if (this.m3_value == v) return; this.m3_value = v; //this.Refresh(); //if (Value3Changed != null) //{ // Value3Changed(this, null); //} } } private Color m_lineColor = Color.FromArgb(255, 77, 59); [Description("线颜色"), Category("自定义")] public Color LineColor { get { return m_lineColor; } set { m_lineColor = value; this.Refresh(); } } RectangleF m_lineRectangle; RectangleF m1_trackRectangle; RectangleF m2_trackRectangle; RectangleF m3_trackRectangle; public UCTrackBar() { this.Size = new Size(250, 30); this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.SetStyle(ControlStyles.DoubleBuffer, true); this.SetStyle(ControlStyles.ResizeRedraw, true); this.SetStyle(ControlStyles.Selectable, true); this.SetStyle(ControlStyles.SupportsTransparentBackColor, true); this.SetStyle(ControlStyles.UserPaint, true); this.MouseDown += UCTrackBar_MouseDown; this.MouseMove += UCTrackBar_MouseMove; this.MouseUp += UCTrackBar_MouseUp; } bool bln1Down = false; bool bln2Down = false; bool bln3Down = false; void UCTrackBar_MouseDown(object sender, MouseEventArgs e) { float locationValue = ((float)e.Location.X / (float)this.Width) * (maxValue - minValue); if (Math.Abs(locationValue - m3_value) < 2 || Math.Abs(locationValue - m2_value) < 2 || Math.Abs(locationValue - m1_value) < 2 ||/*m_lineRectangle.Contains(e.Location) ||*/ m1_trackRectangle.Contains(e.Location) || m2_trackRectangle.Contains(e.Location) || m3_trackRectangle.Contains(e.Location)) { float minValue = Math.Min(Math.Abs(locationValue - m3_value), Math.Min(Math.Abs(locationValue - m2_value), Math.Abs(locationValue - m1_value))); if (Math.Abs(locationValue - m3_value) == minValue) { bln3Down = true; bln2Down = false; bln1Down = false; } //Value = ((float)e.Location.X / (float)this.Width) * (maxValue - minValue); else if (Math.Abs(locationValue - m2_value) == minValue) { bln2Down = true; bln3Down = false; bln1Down = false; } else if (Math.Abs(locationValue - m1_value) == minValue) { bln1Down = true; bln2Down = false; bln3Down = false; } } } void UCTrackBar_MouseMove(object sender, MouseEventArgs e) { if (bln1Down) { float value = ((float)e.Location.X / (float)this.Width) * (maxValue - minValue); if (value > maxValue || value < minValue) return; Value1 = Math.Min(value, Value2 - 1); this.Refresh(); if (Value1Changed != null) { Value1Changed(this, null); } } if (bln2Down) { float value = ((float)e.Location.X / (float)this.Width) * (maxValue - minValue); if (value > maxValue || value < minValue) return; Value2 = Math.Max(Value1 + 1, Math.Min(value, Value3 - 1)); this.Refresh(); if (Value2Changed != null) { Value2Changed(this, null); } } if (bln3Down) { float value = ((float)e.Location.X / (float)this.Width) * (maxValue - minValue); if (value > maxValue || value < minValue) return; Value3 = Math.Max(value, Value2 + 1); this.Refresh(); if (Value3Changed != null) { Value3Changed(this, null); } } } void UCTrackBar_MouseUp(object sender, MouseEventArgs e) { bln1Down = false; bln2Down = false; bln3Down = false; if (ValueMouseUp != null) { ValueMouseUp(this, null); } } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; //g.SetGDIHigh(); m_lineRectangle = new RectangleF(lineWidth, (this.Size.Height - lineWidth) / 2, this.Size.Width - lineWidth * 2, lineWidth); ////GraphicsPath pathLine = ControlHelper.CreateRoundedRectanglePath(m_lineRectangle, 5); ////g.FillPath(new SolidBrush(m_lineColor), pathLine); //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 - 4, lineWidth * 2 - 4); m1_trackRectangle = new RectangleF(m_lineRectangle.Left - lineWidth + (((float)m1_value / (float)(maxValue - minValue)) * (this.Size.Width - lineWidth * 2)), (this.Size.Height - lineWidth * 2) / 2, lineWidth * 2 - 4, lineWidth * 2 - 4); m2_trackRectangle = new RectangleF(m_lineRectangle.Left - lineWidth + (((float)m2_value / (float)(maxValue - minValue)) * (this.Size.Width - lineWidth * 2)), (this.Size.Height - lineWidth * 2) / 2, lineWidth * 2 - 4, lineWidth * 2 - 4); m3_trackRectangle = new RectangleF(m_lineRectangle.Left - lineWidth + (((float)m3_value / (float)(maxValue - minValue)) * (this.Size.Width - lineWidth * 2)), (this.Size.Height - lineWidth * 2) / 2, lineWidth * 2 - 4, lineWidth * 2 - 4); ////m_trackRectangle -= 4; //g.FillEllipse(new SolidBrush(m_lineColor), m1_trackRectangle); //g.FillEllipse(new SolidBrush(m_lineColor), m2_trackRectangle); //g.FillEllipse(new SolidBrush(m_lineColor), m3_trackRectangle); //g.FillEllipse(Brushes.White, new RectangleF(m1_trackRectangle.X + m1_trackRectangle.Width / 4, m1_trackRectangle.Y + m1_trackRectangle.Height / 4, m1_trackRectangle.Width / 2, m1_trackRectangle.Height / 2)); //g.FillEllipse(Brushes.White, new RectangleF(m2_trackRectangle.X + m2_trackRectangle.Width / 4, m2_trackRectangle.Y + m2_trackRectangle.Height / 4, m2_trackRectangle.Width / 2, m2_trackRectangle.Height / 2)); //g.FillEllipse(Brushes.White, new RectangleF(m3_trackRectangle.X + m3_trackRectangle.Width / 4, m3_trackRectangle.Y + m3_trackRectangle.Height / 4, m3_trackRectangle.Width / 2, m3_trackRectangle.Height / 2)); Brush brush = Brushes.Black; //Pen pen = (Pen)Pens.Gray.Clone(); //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias; int triangleHalfLength = 7;// 3 * 2; int triangleSize = 13; int pos1 = triangleHalfLength + (int)(m_lineRectangle.Left - lineWidth + (((float)m1_value / (float)(maxValue - minValue)) * (this.Size.Width - lineWidth * 2))); int pos2 = triangleHalfLength + (int)(m_lineRectangle.Left - lineWidth + (((float)m2_value / (float)(maxValue - minValue)) * (this.Size.Width - lineWidth * 2))); int pos3 = triangleHalfLength + (int)(m_lineRectangle.Left - lineWidth + (((float)m3_value / (float)(maxValue - minValue)) * (this.Size.Width - lineWidth * 2))); Point a1 = new Point(pos1 - triangleHalfLength, triangleSize - 1); Point b1 = new Point(pos1, 0); Point c1 = new Point(pos1 + triangleHalfLength, triangleSize - 1); //Point a2 = new Point(a1.X, Height - 1 - a1.Y); //Point b2 = new Point(b1.X, Height - 1 - b1.Y); //Point c2 = new Point(c1.X, Height - 1 - c1.Y); Point a2 = new Point(pos2 - triangleHalfLength, triangleSize - 1); Point b2 = new Point(pos2, 0); Point c2 = new Point(pos2 + triangleHalfLength, triangleSize - 1); Point a3 = new Point(pos3 - triangleHalfLength, triangleSize - 1); Point b3 = new Point(pos3, 0); Point c3 = new Point(pos3 + triangleHalfLength, triangleSize - 1); g.FillPolygon(brush, new Point[] { a1, b1, c1, a1 }); g.FillPolygon(brush, new Point[] { a2, b2, c2, a2 }); g.FillPolygon(brush, new Point[] { a3, b3, c3, a3 }); //if (this.drawNearNub) //{ // g.FillPolygon(brush, new Point[] { a1, b1, c1, a1 }); //} //if (this.drawFarNub) //{ // g.FillPolygon(brush, new Point[] { a2, b2, c2, a2 }); //} } } } //原文链接:https://blog.csdn.net/kwwwvagaa/article/details/100622682