UCVScrollbar.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. // ***********************************************************************
  2. // Assembly : HZH_Controls
  3. // Created : 2019-09-19
  4. //
  5. // ***********************************************************************
  6. // <copyright file="UCVScrollbar.cs">
  7. // Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com
  8. // </copyright>
  9. //
  10. // Blog: https://www.cnblogs.com/bfyx
  11. // GitHub:https://github.com/kwwwvagaa/NetWinformControl
  12. // gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
  13. //
  14. // If you use this code, please keep this note.
  15. // ***********************************************************************
  16. using System;
  17. using System.Collections.Generic;
  18. using System.ComponentModel;
  19. using System.Drawing;
  20. using System.Data;
  21. using System.Text;
  22. using System.Windows.Forms;
  23. using System.Windows.Forms.Design;
  24. using System.Diagnostics;
  25. namespace HZH_Controls.Controls
  26. {
  27. /// <summary>
  28. /// Class UCVScrollbar.
  29. /// Implements the <see cref="HZH_Controls.Controls.UCControlBase" />
  30. /// </summary>
  31. /// <seealso cref="HZH_Controls.Controls.UCControlBase" />
  32. [Designer(typeof(ScrollbarControlDesigner))]
  33. [DefaultEvent("Scroll")]
  34. public class UCVScrollbar : UCControlBase
  35. {
  36. /// <summary>
  37. /// The mo large change
  38. /// </summary>
  39. protected int moLargeChange = 10;
  40. /// <summary>
  41. /// The mo small change
  42. /// </summary>
  43. protected int moSmallChange = 1;
  44. /// <summary>
  45. /// The mo minimum
  46. /// </summary>
  47. protected int moMinimum = 0;
  48. /// <summary>
  49. /// The mo maximum
  50. /// </summary>
  51. protected int moMaximum = 100;
  52. /// <summary>
  53. /// The mo value
  54. /// </summary>
  55. protected int moValue = 0;
  56. /// <summary>
  57. /// The n click point
  58. /// </summary>
  59. private int nClickPoint;
  60. /// <summary>
  61. /// The mo thumb top
  62. /// </summary>
  63. protected int moThumbTop = 0;
  64. /// <summary>
  65. /// The mo automatic size
  66. /// </summary>
  67. protected bool moAutoSize = false;
  68. /// <summary>
  69. /// The mo thumb down
  70. /// </summary>
  71. private bool moThumbMouseDown = false;
  72. /// <summary>
  73. /// The mo thumb dragging
  74. /// </summary>
  75. private bool moThumbMouseDragging = false;
  76. /// <summary>
  77. /// Occurs when [scroll].
  78. /// </summary>
  79. public new event EventHandler Scroll = null;
  80. /// <summary>
  81. /// Occurs when [value changed].
  82. /// </summary>
  83. public event EventHandler ValueChanged = null;
  84. /// <summary>
  85. /// The BTN height
  86. /// </summary>
  87. private int btnHeight = 18;
  88. /// <summary>
  89. /// The m int thumb minimum height
  90. /// </summary>
  91. private int m_intThumbMinHeight = 15;
  92. /// <summary>
  93. /// Gets or sets the height of the BTN.
  94. /// </summary>
  95. /// <value>The height of the BTN.</value>
  96. public int BtnHeight
  97. {
  98. get { return btnHeight; }
  99. set { btnHeight = value; }
  100. }
  101. /// <summary>
  102. /// Gets or sets the large change.
  103. /// </summary>
  104. /// <value>The large change.</value>
  105. [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("自定义"), Description("LargeChange")]
  106. public int LargeChange
  107. {
  108. get { return moLargeChange; }
  109. set
  110. {
  111. moLargeChange = value;
  112. Invalidate();
  113. }
  114. }
  115. /// <summary>
  116. /// Gets or sets the small change.
  117. /// </summary>
  118. /// <value>The small change.</value>
  119. [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("自定义"), Description("SmallChange")]
  120. public int SmallChange
  121. {
  122. get { return moSmallChange; }
  123. set
  124. {
  125. moSmallChange = value;
  126. Invalidate();
  127. }
  128. }
  129. /// <summary>
  130. /// Gets or sets the minimum.
  131. /// </summary>
  132. /// <value>The minimum.</value>
  133. [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("自定义"), Description("Minimum")]
  134. public int Minimum
  135. {
  136. get { return moMinimum; }
  137. set
  138. {
  139. moMinimum = value;
  140. Invalidate();
  141. }
  142. }
  143. /// <summary>
  144. /// Gets or sets the maximum.
  145. /// </summary>
  146. /// <value>The maximum.</value>
  147. [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("自定义"), Description("Maximum")]
  148. public int Maximum
  149. {
  150. get { return moMaximum; }
  151. set
  152. {
  153. moMaximum = value;
  154. Invalidate();
  155. }
  156. }
  157. /// <summary>
  158. /// Gets or sets the value.
  159. /// </summary>
  160. /// <value>The value.</value>
  161. [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("自定义"), Description("Value")]
  162. public int Value
  163. {
  164. get { return moValue; }
  165. set
  166. {
  167. moValue = value;
  168. int nTrackHeight = (this.Height - btnHeight * 2);
  169. float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
  170. int nThumbHeight = (int)fThumbHeight;
  171. if (nThumbHeight > nTrackHeight)
  172. {
  173. nThumbHeight = nTrackHeight;
  174. fThumbHeight = nTrackHeight;
  175. }
  176. if (nThumbHeight < m_intThumbMinHeight)
  177. {
  178. nThumbHeight = m_intThumbMinHeight;
  179. fThumbHeight = m_intThumbMinHeight;
  180. }
  181. //figure out value
  182. int nPixelRange = nTrackHeight - nThumbHeight;
  183. int nRealRange = (Maximum - Minimum) - LargeChange;
  184. float fPerc = 0.0f;
  185. if (nRealRange != 0)
  186. {
  187. fPerc = (float)moValue / (float)nRealRange;
  188. }
  189. float fTop = fPerc * nPixelRange;
  190. moThumbTop = (int)fTop;
  191. Invalidate();
  192. }
  193. }
  194. /// <summary>
  195. /// Gets or sets a value indicating whether [automatic size].
  196. /// </summary>
  197. /// <value><c>true</c> if [automatic size]; otherwise, <c>false</c>.</value>
  198. public override bool AutoSize
  199. {
  200. get
  201. {
  202. return base.AutoSize;
  203. }
  204. set
  205. {
  206. base.AutoSize = value;
  207. if (base.AutoSize)
  208. {
  209. this.Width = 15;
  210. }
  211. }
  212. }
  213. /// <summary>
  214. /// The thumb color
  215. /// </summary>
  216. private Color thumbColor = Color.FromArgb(255, 77, 58);
  217. /// <summary>
  218. /// Gets or sets the color of the thumb.
  219. /// </summary>
  220. /// <value>The color of the thumb.</value>
  221. public Color ThumbColor
  222. {
  223. get { return thumbColor; }
  224. set { thumbColor = value; }
  225. }
  226. /// <summary>
  227. /// Initializes a new instance of the <see cref="UCVScrollbar"/> class.
  228. /// </summary>
  229. public UCVScrollbar()
  230. {
  231. InitializeComponent();
  232. ConerRadius = 2;
  233. FillColor = Color.FromArgb(239, 239, 239);
  234. IsShowRect = false;
  235. IsRadius = true;
  236. this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  237. this.SetStyle(ControlStyles.DoubleBuffer, true);
  238. this.SetStyle(ControlStyles.ResizeRedraw, true);
  239. this.SetStyle(ControlStyles.Selectable, true);
  240. this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
  241. this.SetStyle(ControlStyles.UserPaint, true);
  242. }
  243. /// <summary>
  244. /// Initializes the component.
  245. /// </summary>
  246. private void InitializeComponent()
  247. {
  248. this.SuspendLayout();
  249. //
  250. // UCVScrollbar
  251. //
  252. this.MinimumSize = new System.Drawing.Size(10, 0);
  253. this.Name = "UCVScrollbar";
  254. this.Size = new System.Drawing.Size(18, 150);
  255. this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.CustomScrollbar_MouseDown);
  256. this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.CustomScrollbar_MouseMove);
  257. this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.CustomScrollbar_MouseUp);
  258. this.ResumeLayout(false);
  259. }
  260. /// <summary>
  261. /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
  262. /// </summary>
  263. /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
  264. protected override void OnPaint(PaintEventArgs e)
  265. {
  266. base.OnPaint(e);
  267. e.Graphics.SetGDIHigh();
  268. //draw thumb
  269. int nTrackHeight = (this.Height - btnHeight * 2);
  270. float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
  271. int nThumbHeight = (int)fThumbHeight;
  272. if (nThumbHeight > nTrackHeight)
  273. {
  274. nThumbHeight = nTrackHeight;
  275. fThumbHeight = nTrackHeight;
  276. }
  277. if (nThumbHeight < m_intThumbMinHeight)
  278. {
  279. nThumbHeight = m_intThumbMinHeight;
  280. fThumbHeight = m_intThumbMinHeight;
  281. }
  282. int nTop = moThumbTop;
  283. nTop += btnHeight;
  284. e.Graphics.FillPath(new SolidBrush(thumbColor), new Rectangle(1, nTop, this.Width - 3, nThumbHeight).CreateRoundedRectanglePath(this.ConerRadius));
  285. ControlHelper.PaintTriangle(e.Graphics, new SolidBrush(thumbColor), new Point(this.Width / 2, btnHeight - Math.Min(5, this.Width / 2)), Math.Min(5, this.Width / 2), GraphDirection.Upward);
  286. ControlHelper.PaintTriangle(e.Graphics, new SolidBrush(thumbColor), new Point(this.Width / 2, this.Height - (btnHeight - Math.Min(5, this.Width / 2))), Math.Min(5, this.Width / 2), GraphDirection.Downward);
  287. }
  288. /// <summary>
  289. /// Handles the MouseDown event of the CustomScrollbar control.
  290. /// </summary>
  291. /// <param name="sender">The source of the event.</param>
  292. /// <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
  293. private void CustomScrollbar_MouseDown(object sender, MouseEventArgs e)
  294. {
  295. Point ptPoint = this.PointToClient(Cursor.Position);
  296. int nTrackHeight = (this.Height - btnHeight * 2);
  297. float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
  298. int nThumbHeight = (int)fThumbHeight;
  299. if (nThumbHeight > nTrackHeight)
  300. {
  301. nThumbHeight = nTrackHeight;
  302. fThumbHeight = nTrackHeight;
  303. }
  304. if (nThumbHeight < m_intThumbMinHeight)
  305. {
  306. nThumbHeight = m_intThumbMinHeight;
  307. fThumbHeight = m_intThumbMinHeight;
  308. }
  309. int nTop = moThumbTop;
  310. nTop += btnHeight;
  311. Rectangle thumbrect = new Rectangle(new Point(1, nTop), new Size(this.Width - 2, nThumbHeight));
  312. if (thumbrect.Contains(ptPoint))
  313. {
  314. //hit the thumb
  315. nClickPoint = (ptPoint.Y - nTop);
  316. //MessageBox.Show(Convert.ToString((ptPoint.Y - nTop)));
  317. this.moThumbMouseDown = true;
  318. }
  319. else
  320. {
  321. Rectangle uparrowrect = new Rectangle(new Point(1, 0), new Size(this.Width, btnHeight));
  322. if (uparrowrect.Contains(ptPoint))
  323. {
  324. int nRealRange = (Maximum - Minimum) - LargeChange;
  325. int nPixelRange = (nTrackHeight - nThumbHeight);
  326. if (nRealRange > 0)
  327. {
  328. if (nPixelRange > 0)
  329. {
  330. if ((moThumbTop - SmallChange) < 0)
  331. moThumbTop = 0;
  332. else
  333. moThumbTop -= SmallChange;
  334. //figure out value
  335. float fPerc = (float)moThumbTop / (float)nPixelRange;
  336. float fValue = fPerc * (Maximum - LargeChange);
  337. moValue = (int)fValue;
  338. if (ValueChanged != null)
  339. ValueChanged(this, new EventArgs());
  340. if (Scroll != null)
  341. Scroll(this, new EventArgs());
  342. Invalidate();
  343. }
  344. }
  345. }
  346. else
  347. {
  348. Rectangle downarrowrect = new Rectangle(new Point(1, btnHeight + nTrackHeight), new Size(this.Width, btnHeight));
  349. if (downarrowrect.Contains(ptPoint))
  350. {
  351. int nRealRange = (Maximum - Minimum) - LargeChange;
  352. int nPixelRange = (nTrackHeight - nThumbHeight);
  353. if (nRealRange > 0)
  354. {
  355. if (nPixelRange > 0)
  356. {
  357. if ((moThumbTop + SmallChange) > nPixelRange)
  358. moThumbTop = nPixelRange;
  359. else
  360. moThumbTop += SmallChange;
  361. //figure out value
  362. float fPerc = (float)moThumbTop / (float)nPixelRange;
  363. float fValue = fPerc * (Maximum - LargeChange);
  364. moValue = (int)fValue;
  365. if (ValueChanged != null)
  366. ValueChanged(this, new EventArgs());
  367. if (Scroll != null)
  368. Scroll(this, new EventArgs());
  369. Invalidate();
  370. }
  371. }
  372. }
  373. }
  374. }
  375. }
  376. /// <summary>
  377. /// Handles the MouseUp event of the CustomScrollbar control.
  378. /// </summary>
  379. /// <param name="sender">The source of the event.</param>
  380. /// <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
  381. private void CustomScrollbar_MouseUp(object sender, MouseEventArgs e)
  382. {
  383. this.moThumbMouseDown = false;
  384. this.moThumbMouseDragging = false;
  385. }
  386. /// <summary>
  387. /// Moves the thumb.
  388. /// </summary>
  389. /// <param name="y">The y.</param>
  390. private void MoveThumb(int y)
  391. {
  392. int nRealRange = Maximum - Minimum;
  393. int nTrackHeight = (this.Height - btnHeight * 2);
  394. float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
  395. int nThumbHeight = (int)fThumbHeight;
  396. if (nThumbHeight > nTrackHeight)
  397. {
  398. nThumbHeight = nTrackHeight;
  399. fThumbHeight = nTrackHeight;
  400. }
  401. if (nThumbHeight < m_intThumbMinHeight)
  402. {
  403. nThumbHeight = m_intThumbMinHeight;
  404. fThumbHeight = m_intThumbMinHeight;
  405. }
  406. int nSpot = nClickPoint;
  407. int nPixelRange = (nTrackHeight - nThumbHeight);
  408. if (moThumbMouseDown && nRealRange > 0)
  409. {
  410. if (nPixelRange > 0)
  411. {
  412. int nNewThumbTop = y - (btnHeight + nSpot);
  413. if (nNewThumbTop < 0)
  414. {
  415. moThumbTop = nNewThumbTop = 0;
  416. }
  417. else if (nNewThumbTop > nPixelRange)
  418. {
  419. moThumbTop = nNewThumbTop = nPixelRange;
  420. }
  421. else
  422. {
  423. moThumbTop = y - (btnHeight + nSpot);
  424. }
  425. float fPerc = (float)moThumbTop / (float)nPixelRange;
  426. float fValue = fPerc * (Maximum - LargeChange);
  427. moValue = (int)fValue;
  428. Application.DoEvents();
  429. Invalidate();
  430. }
  431. }
  432. }
  433. /// <summary>
  434. /// Handles the MouseMove event of the CustomScrollbar control.
  435. /// </summary>
  436. /// <param name="sender">The source of the event.</param>
  437. /// <param name="e">The <see cref="MouseEventArgs"/> instance containing the event data.</param>
  438. private void CustomScrollbar_MouseMove(object sender, MouseEventArgs e)
  439. {
  440. if (!moThumbMouseDown)
  441. return;
  442. if (moThumbMouseDown == true)
  443. {
  444. this.moThumbMouseDragging = true;
  445. }
  446. if (this.moThumbMouseDragging)
  447. {
  448. MoveThumb(e.Y);
  449. }
  450. if (ValueChanged != null)
  451. ValueChanged(this, new EventArgs());
  452. if (Scroll != null)
  453. Scroll(this, new EventArgs());
  454. }
  455. }
  456. }