UCTrackBar.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. using System;
  2. using System.Windows.Forms;
  3. using System.Drawing;
  4. using System.ComponentModel;
  5. namespace PaintDotNet.CustomControl
  6. {
  7. public partial class UCTrackBar : Control
  8. {
  9. [Description("Left值改变事件"), Category("自定义")]
  10. public event EventHandler Value1Changed;
  11. [Description("Center值改变事件"), Category("自定义")]
  12. public event EventHandler Value2Changed;
  13. [Description("Right值改变事件"), Category("自定义")]
  14. public event EventHandler Value3Changed;
  15. private int dcimalDigits = 0;
  16. [Description("值小数精确位数"), Category("自定义")]
  17. public int DcimalDigits
  18. {
  19. get { return dcimalDigits; }
  20. set { dcimalDigits = value; }
  21. }
  22. private float lineWidth = 10;
  23. [Description("线宽度"), Category("自定义")]
  24. public float LineWidth
  25. {
  26. get { return lineWidth; }
  27. set { lineWidth = value; }
  28. }
  29. private float minValue = 0;
  30. [Description("最小值"), Category("自定义")]
  31. public float MinValue
  32. {
  33. get { return minValue; }
  34. set
  35. {
  36. if (minValue > m1_value)
  37. return;
  38. if (minValue > m2_value)
  39. return;
  40. if (minValue > m3_value)
  41. return;
  42. minValue = value;
  43. this.Refresh();
  44. }
  45. }
  46. private float maxValue = 255;//256;
  47. [Description("最大值"), Category("自定义")]
  48. public float MaxValue
  49. {
  50. get { return maxValue; }
  51. set
  52. {
  53. if (value < m1_value)
  54. return;
  55. if (value < m2_value)
  56. return;
  57. if (value < m3_value)
  58. return;
  59. maxValue = value;
  60. this.Refresh();
  61. }
  62. }
  63. private float m1_value = 0;//2;//0;
  64. private float m2_value = 127;//128;
  65. private float m3_value = 255;//254;//256;
  66. [Description("Left值"), Category("自定义")]
  67. public float Value1
  68. {
  69. get { return this.m1_value; }
  70. set
  71. {
  72. if (value > maxValue || value < minValue)
  73. return;
  74. var v = (float)Math.Round((double)value, dcimalDigits);
  75. if (this.m1_value == v)
  76. return;
  77. this.m1_value = v;
  78. }
  79. }
  80. [Description("Center值"), Category("自定义")]
  81. public float Value2
  82. {
  83. get { return this.m2_value; }
  84. set
  85. {
  86. if (value > maxValue || value < minValue)
  87. return;
  88. var v = (float)Math.Round((double)value, dcimalDigits);
  89. if (this.m2_value == v)
  90. return;
  91. this.m2_value = v;
  92. //this.Refresh();
  93. //if (Value2Changed != null)
  94. //{
  95. // Value2Changed(this, null);
  96. //}
  97. }
  98. }
  99. [Description("Right值"), Category("自定义")]
  100. public float Value3
  101. {
  102. get { return this.m3_value; }
  103. set
  104. {
  105. if (value > maxValue || value < minValue)
  106. return;
  107. var v = (float)Math.Round((double)value, dcimalDigits);
  108. if (this.m3_value == v)
  109. return;
  110. this.m3_value = v;
  111. //this.Refresh();
  112. //if (Value3Changed != null)
  113. //{
  114. // Value3Changed(this, null);
  115. //}
  116. }
  117. }
  118. private Color m_lineColor = Color.FromArgb(255, 77, 59);
  119. [Description("线颜色"), Category("自定义")]
  120. public Color LineColor
  121. {
  122. get { return m_lineColor; }
  123. set
  124. {
  125. m_lineColor = value;
  126. this.Refresh();
  127. }
  128. }
  129. RectangleF m_lineRectangle;
  130. RectangleF m1_trackRectangle;
  131. RectangleF m2_trackRectangle;
  132. RectangleF m3_trackRectangle;
  133. public UCTrackBar()
  134. {
  135. this.Size = new Size(250, 30);
  136. this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  137. this.SetStyle(ControlStyles.DoubleBuffer, true);
  138. this.SetStyle(ControlStyles.ResizeRedraw, true);
  139. this.SetStyle(ControlStyles.Selectable, true);
  140. this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
  141. this.SetStyle(ControlStyles.UserPaint, true);
  142. this.MouseDown += UCTrackBar_MouseDown;
  143. this.MouseMove += UCTrackBar_MouseMove;
  144. this.MouseUp += UCTrackBar_MouseUp;
  145. }
  146. bool bln1Down = false;
  147. bool bln2Down = false;
  148. bool bln3Down = false;
  149. void UCTrackBar_MouseDown(object sender, MouseEventArgs e)
  150. {
  151. float locationValue = ((float)e.Location.X / (float)this.Width) * (maxValue - minValue);
  152. 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))
  153. {
  154. float minValue = Math.Min(Math.Abs(locationValue - m3_value), Math.Min(Math.Abs(locationValue - m2_value), Math.Abs(locationValue - m1_value)));
  155. if (Math.Abs(locationValue - m3_value) == minValue)
  156. {
  157. bln3Down = true;
  158. bln2Down = false;
  159. bln1Down = false;
  160. }
  161. //Value = ((float)e.Location.X / (float)this.Width) * (maxValue - minValue);
  162. else if (Math.Abs(locationValue - m2_value) == minValue)
  163. {
  164. bln2Down = true;
  165. bln3Down = false;
  166. bln1Down = false;
  167. }
  168. else if (Math.Abs(locationValue - m1_value) == minValue)
  169. {
  170. bln1Down = true;
  171. bln2Down = false;
  172. bln3Down = false;
  173. }
  174. }
  175. }
  176. void UCTrackBar_MouseMove(object sender, MouseEventArgs e)
  177. {
  178. if (bln1Down)
  179. {
  180. float value = ((float)e.Location.X / (float)this.Width) * (maxValue - minValue);
  181. if (value > maxValue || value < minValue)
  182. return;
  183. Value1 = Math.Min(value, Value2 - 1);
  184. this.Refresh();
  185. if (Value1Changed != null)
  186. {
  187. Value1Changed(this, null);
  188. }
  189. }
  190. if (bln2Down)
  191. {
  192. float value = ((float)e.Location.X / (float)this.Width) * (maxValue - minValue);
  193. if (value > maxValue || value < minValue)
  194. return;
  195. Value2 = Math.Max(Value1 + 1, Math.Min(value, Value3 - 1));
  196. this.Refresh();
  197. if (Value2Changed != null)
  198. {
  199. Value2Changed(this, null);
  200. }
  201. }
  202. if (bln3Down)
  203. {
  204. float value = ((float)e.Location.X / (float)this.Width) * (maxValue - minValue);
  205. if (value > maxValue || value < minValue)
  206. return;
  207. Value3 = Math.Max(value, Value2 + 1);
  208. this.Refresh();
  209. if (Value3Changed != null)
  210. {
  211. Value3Changed(this, null);
  212. }
  213. }
  214. }
  215. void UCTrackBar_MouseUp(object sender, MouseEventArgs e)
  216. {
  217. bln1Down = false;
  218. bln2Down = false;
  219. bln3Down = false;
  220. }
  221. protected override void OnPaint(PaintEventArgs e)
  222. {
  223. base.OnPaint(e);
  224. Graphics g = e.Graphics;
  225. //g.SetGDIHigh();
  226. m_lineRectangle = new RectangleF(lineWidth, (this.Size.Height - lineWidth) / 2, this.Size.Width - lineWidth * 2, lineWidth);
  227. ////GraphicsPath pathLine = ControlHelper.CreateRoundedRectanglePath(m_lineRectangle, 5);
  228. ////g.FillPath(new SolidBrush(m_lineColor), pathLine);
  229. //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);
  230. 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);
  231. 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);
  232. 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);
  233. ////m_trackRectangle -= 4;
  234. //g.FillEllipse(new SolidBrush(m_lineColor), m1_trackRectangle);
  235. //g.FillEllipse(new SolidBrush(m_lineColor), m2_trackRectangle);
  236. //g.FillEllipse(new SolidBrush(m_lineColor), m3_trackRectangle);
  237. //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));
  238. //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));
  239. //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));
  240. Brush brush = Brushes.Black;
  241. //Pen pen = (Pen)Pens.Gray.Clone();
  242. //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
  243. int triangleHalfLength = 7;// 3 * 2;
  244. int triangleSize = 13;
  245. int pos1 = triangleHalfLength + (int)(m_lineRectangle.Left - lineWidth + (((float)m1_value / (float)(maxValue - minValue)) * (this.Size.Width - lineWidth * 2)));
  246. int pos2 = triangleHalfLength + (int)(m_lineRectangle.Left - lineWidth + (((float)m2_value / (float)(maxValue - minValue)) * (this.Size.Width - lineWidth * 2)));
  247. int pos3 = triangleHalfLength + (int)(m_lineRectangle.Left - lineWidth + (((float)m3_value / (float)(maxValue - minValue)) * (this.Size.Width - lineWidth * 2)));
  248. Point a1 = new Point(pos1 - triangleHalfLength, triangleSize - 1);
  249. Point b1 = new Point(pos1, 0);
  250. Point c1 = new Point(pos1 + triangleHalfLength, triangleSize - 1);
  251. //Point a2 = new Point(a1.X, Height - 1 - a1.Y);
  252. //Point b2 = new Point(b1.X, Height - 1 - b1.Y);
  253. //Point c2 = new Point(c1.X, Height - 1 - c1.Y);
  254. Point a2 = new Point(pos2 - triangleHalfLength, triangleSize - 1);
  255. Point b2 = new Point(pos2, 0);
  256. Point c2 = new Point(pos2 + triangleHalfLength, triangleSize - 1);
  257. Point a3 = new Point(pos3 - triangleHalfLength, triangleSize - 1);
  258. Point b3 = new Point(pos3, 0);
  259. Point c3 = new Point(pos3 + triangleHalfLength, triangleSize - 1);
  260. g.FillPolygon(brush, new Point[] { a1, b1, c1, a1 });
  261. g.FillPolygon(brush, new Point[] { a2, b2, c2, a2 });
  262. g.FillPolygon(brush, new Point[] { a3, b3, c3, a3 });
  263. //if (this.drawNearNub)
  264. //{
  265. // g.FillPolygon(brush, new Point[] { a1, b1, c1, a1 });
  266. //}
  267. //if (this.drawFarNub)
  268. //{
  269. // g.FillPolygon(brush, new Point[] { a2, b2, c2, a2 });
  270. //}
  271. }
  272. }
  273. }
  274. //————————————————
  275. //版权声明:本文为CSDN博主「kwwwvagaa」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
  276. //原文链接:https://blog.csdn.net/kwwwvagaa/article/details/100622682