Arrow.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Drawing.Drawing2D;
  7. using System.Linq;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. using System.Windows.Forms;
  11. namespace monitor_main_windows
  12. {
  13. public partial class Arrow : UserControl
  14. {
  15. public Arrow()
  16. {
  17. InitializeComponent();
  18. this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  19. this.SetStyle(ControlStyles.DoubleBuffer, true);
  20. this.SetStyle(ControlStyles.ResizeRedraw, true);
  21. this.SetStyle(ControlStyles.Selectable, true);
  22. this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
  23. this.SetStyle(ControlStyles.UserPaint, true);
  24. this.ForeColor = Color.White;
  25. this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
  26. this.SizeChanged += Arrow_SizeChanged;
  27. this.Size = new Size(100, 50);
  28. }
  29. /// <summary>
  30. /// The arrow color
  31. /// </summary>
  32. private Color arrowColor = Color.FromArgb(255, 77, 59);
  33. /// <summary>
  34. /// Gets or sets the color of the arrow.
  35. /// </summary>
  36. /// <value>The color of the arrow.</value>
  37. [Description("箭头颜色"), Category("自定义")]
  38. public Color ArrowColor
  39. {
  40. get { return arrowColor; }
  41. set
  42. {
  43. arrowColor = value;
  44. Refresh();
  45. }
  46. }
  47. /// <summary>
  48. /// The border color
  49. /// </summary>
  50. private Color? borderColor = null;
  51. /// <summary>
  52. /// Gets or sets the color of the border.
  53. /// </summary>
  54. /// <value>The color of the border.</value>
  55. [Description("箭头边框颜色,为空则无边框"), Category("自定义")]
  56. public Color? BorderColor
  57. {
  58. get { return borderColor; }
  59. set
  60. {
  61. borderColor = value;
  62. Refresh();
  63. }
  64. }
  65. /// <summary>
  66. /// The direction
  67. /// </summary>
  68. private ArrowDirection direction = monitor_main_windows.ArrowDirection.Right;
  69. /// <summary>
  70. /// Gets or sets the direction.
  71. /// </summary>
  72. /// <value>The direction.</value>
  73. [Description("箭头方向"), Category("自定义")]
  74. public ArrowDirection Direction
  75. {
  76. get { return direction; }
  77. set
  78. {
  79. direction = value;
  80. ResetPath();
  81. Refresh();
  82. }
  83. }
  84. /// <summary>
  85. /// 获取或设置控件显示的文字的字体。
  86. /// </summary>
  87. /// <value>The font.</value>
  88. /// <PermissionSet>
  89. /// <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
  90. /// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
  91. /// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence" />
  92. /// <IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
  93. /// </PermissionSet>
  94. public override Font Font
  95. {
  96. get
  97. {
  98. return base.Font;
  99. }
  100. set
  101. {
  102. base.Font = value;
  103. Refresh();
  104. }
  105. }
  106. /// <summary>
  107. /// 获取或设置控件的前景色。
  108. /// </summary>
  109. /// <value>The color of the fore.</value>
  110. /// <PermissionSet>
  111. /// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
  112. /// </PermissionSet>
  113. public override Color ForeColor
  114. {
  115. get
  116. {
  117. return base.ForeColor;
  118. }
  119. set
  120. {
  121. base.ForeColor = value;
  122. Refresh();
  123. }
  124. }
  125. /// <summary>
  126. /// The text
  127. /// </summary>
  128. private string text;
  129. /// <summary>
  130. /// Gets or sets the text.
  131. /// </summary>
  132. /// <value>The text.</value>
  133. [Bindable(true)]
  134. [Browsable(true)]
  135. [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
  136. [EditorBrowsable(EditorBrowsableState.Always)]
  137. [Localizable(true)]
  138. [Description("箭头文字"), Category("自定义")]
  139. public override string Text
  140. {
  141. get
  142. {
  143. return text;
  144. }
  145. set
  146. {
  147. text = value;
  148. Refresh();
  149. }
  150. }
  151. /// <summary>
  152. /// The m path
  153. /// </summary>
  154. GraphicsPath m_path;
  155. /// <summary>
  156. /// Initializes a new instance of the <see cref="UCArrow" /> class.
  157. /// <summary>
  158. /// Handles the SizeChanged event of the UCArrow control.
  159. /// </summary>
  160. /// <param name="sender">The source of the event.</param>
  161. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  162. void Arrow_SizeChanged(object sender, EventArgs e)
  163. {
  164. ResetPath();
  165. }
  166. /// <summary>
  167. /// Resets the path.
  168. /// </summary>
  169. private void ResetPath()
  170. {
  171. Point[] ps = null;
  172. int arrow_h = 20;
  173. switch (direction)
  174. {
  175. case ArrowDirection.Left:
  176. arrow_h = Width / 3+1;
  177. ps = new Point[]
  178. {
  179. new Point(0,this.Height/2),
  180. new Point(arrow_h,0),
  181. new Point(arrow_h,this.Height/4),
  182. new Point(this.Width-1,this.Height/4),
  183. new Point(this.Width-1,this.Height-this.Height/4),
  184. new Point(arrow_h,this.Height-this.Height/4),
  185. new Point(arrow_h,this.Height),
  186. new Point(0,this.Height/2)
  187. };
  188. break;
  189. case ArrowDirection.Right:
  190. arrow_h = Width / 3 + 1;
  191. ps = new Point[]
  192. {
  193. new Point(0,this.Height/4),
  194. new Point(this.Width-arrow_h,this.Height/4),
  195. new Point(this.Width-arrow_h,0),
  196. new Point(this.Width-1,this.Height/2),
  197. new Point(this.Width-arrow_h,this.Height),
  198. new Point(this.Width-arrow_h,this.Height-this.Height/4),
  199. new Point(0,this.Height-this.Height/4),
  200. new Point(0,this.Height/4)
  201. };
  202. break;
  203. case ArrowDirection.Top:
  204. arrow_h = Height / 3 + 1;
  205. ps = new Point[]
  206. {
  207. new Point(this.Width/2,0),
  208. new Point(this.Width,arrow_h),
  209. new Point(this.Width-this.Width/4,arrow_h),
  210. new Point(this.Width-this.Width/4,this.Height-1),
  211. new Point(this.Width/4,this.Height-1),
  212. new Point(this.Width/4,arrow_h),
  213. new Point(0,arrow_h),
  214. new Point(this.Width/2,0),
  215. };
  216. break;
  217. case ArrowDirection.Bottom:
  218. arrow_h = Height / 3 + 1;
  219. ps = new Point[]
  220. {
  221. new Point(this.Width-this.Width/4,0),
  222. new Point(this.Width-this.Width/4,this.Height-arrow_h),
  223. new Point(this.Width,this.Height-arrow_h),
  224. new Point(this.Width/2,this.Height-1),
  225. new Point(0,this.Height-arrow_h),
  226. new Point(this.Width/4,this.Height-arrow_h),
  227. new Point(this.Width/4,0),
  228. new Point(this.Width-this.Width/4,0),
  229. };
  230. break;
  231. case ArrowDirection.Left_Right:
  232. ps = new Point[]
  233. {
  234. new Point(0,this.Height/2),
  235. new Point(arrow_h,0),
  236. new Point(arrow_h,this.Height/4),
  237. new Point(this.Width-arrow_h,this.Height/4),
  238. new Point(this.Width-arrow_h,0),
  239. new Point(this.Width-1,this.Height/2),
  240. new Point(this.Width-arrow_h,this.Height),
  241. new Point(this.Width-arrow_h,this.Height-this.Height/4),
  242. new Point(arrow_h,this.Height-this.Height/4),
  243. new Point(arrow_h,this.Height),
  244. new Point(0,this.Height/2),
  245. };
  246. break;
  247. case ArrowDirection.Top_Bottom:
  248. ps = new Point[]
  249. {
  250. new Point(this.Width/2,0),
  251. new Point(this.Width,arrow_h),
  252. new Point(this.Width-this.Width/4,arrow_h),
  253. new Point(this.Width-this.Width/4,this.Height-arrow_h),
  254. new Point(this.Width,this.Height-arrow_h),
  255. new Point(this.Width/2,this.Height-1),
  256. new Point(0,this.Height-arrow_h),
  257. new Point(this.Width/4,this.Height-arrow_h),
  258. new Point(this.Width/4,arrow_h),
  259. new Point(0,arrow_h),
  260. new Point(this.Width/2,0),
  261. };
  262. break;
  263. case ArrowDirection.TopRight:
  264. arrow_h = Math.Min(Width / 5, Height / 3);
  265. ps = new Point[]
  266. {
  267. new Point(Width/2+5*arrow_h/2,Height/2-arrow_h/2),
  268. new Point(Width/2+3*arrow_h/2,Height/2-3*arrow_h/2),
  269. new Point(Width/2+3*arrow_h/2,Height/2-arrow_h),
  270. new Point(Width/2+arrow_h/2,Height/2-arrow_h),
  271. new Point(Width/2+arrow_h/2,Height/2),
  272. new Point(Width/2+3*arrow_h/2,Height/2),
  273. new Point(Width/2+3*arrow_h/2,Height/2+arrow_h/2),
  274. new Point(Width/2+5*arrow_h/2,Height/2-arrow_h/2)
  275. };
  276. break;
  277. case ArrowDirection.TopLeft:
  278. arrow_h = Math.Min(Width / 5, Height / 3);
  279. ps = new Point[]
  280. {
  281. new Point(Width/2-5*arrow_h/2,Height/2-arrow_h/2),
  282. new Point(Width/2-3*arrow_h/2,Height/2-3*arrow_h/2),
  283. new Point(Width/2-3*arrow_h/2,Height/2-arrow_h),
  284. new Point(Width/2-arrow_h/2+1,Height/2-arrow_h),
  285. new Point(Width/2-arrow_h/2+1,Height/2),
  286. new Point(Width/2-3*arrow_h/2,Height/2),
  287. new Point(Width/2-3*arrow_h/2,Height/2+arrow_h/2),
  288. new Point(Width/2-5*arrow_h/2,Height/2-arrow_h/2)
  289. };
  290. break;
  291. case ArrowDirection.LeftTop:
  292. arrow_h = Math.Min(Width /3, Height /5);
  293. ps = new Point[]
  294. {
  295. new Point(Width/2-arrow_h/2,Height/2-5*arrow_h/2),
  296. new Point(Width/2-3*arrow_h/2,Height/2-3*arrow_h/2),
  297. new Point(Width/2-arrow_h,Height/2-3*arrow_h/2),
  298. new Point(Width/2-arrow_h,Height/2-arrow_h/2+1),
  299. new Point(Width/2,Height/2-arrow_h/2+1),
  300. new Point(Width/2,Height/2-3*arrow_h/2),
  301. new Point(Width/2+arrow_h/2,Height/2-3*arrow_h/2),
  302. new Point(Width/2-arrow_h/2,Height/2-5*arrow_h/2)
  303. };
  304. break;
  305. case ArrowDirection.LeftDown:
  306. arrow_h = Math.Min(Width / 3, Height / 5);
  307. ps = new Point[]
  308. {
  309. new Point(Width/2-arrow_h/2,Height/2+5*arrow_h/2),
  310. new Point(Width/2-3*arrow_h/2,Height/2+3*arrow_h/2),
  311. new Point(Width/2-arrow_h,Height/2+3*arrow_h/2),
  312. new Point(Width/2-arrow_h,Height/2+arrow_h/2-1),
  313. new Point(Width/2,Height/2+arrow_h/2-1),
  314. new Point(Width/2,Height/2+3*arrow_h/2),
  315. new Point(Width/2+arrow_h/2,Height/2+3*arrow_h/2),
  316. new Point(Width/2-arrow_h/2,Height/2+5*arrow_h/2)
  317. };
  318. break;
  319. case ArrowDirection.RightTop:
  320. arrow_h = Math.Min(Width / 3, Height / 5);
  321. ps = new Point[]
  322. {
  323. new Point(Width/2+arrow_h/2,Height/2-5*arrow_h/2),
  324. new Point(Width/2+3*arrow_h/2,Height/2-3*arrow_h/2),
  325. new Point(Width/2+arrow_h,Height/2-3*arrow_h/2),
  326. new Point(Width/2+arrow_h,Height/2-arrow_h/2+1),
  327. new Point(Width/2,Height/2-arrow_h/2+1),
  328. new Point(Width/2,Height/2-3*arrow_h/2),
  329. new Point(Width/2-arrow_h/2,Height/2-3*arrow_h/2),
  330. new Point(Width/2+arrow_h/2,Height/2-5*arrow_h/2)
  331. };
  332. break;
  333. case ArrowDirection.RightDown:
  334. arrow_h = Math.Min(Width / 3, Height / 5);
  335. ps = new Point[]
  336. {
  337. new Point(Width/2+arrow_h/2,Height/2+5*arrow_h/2),
  338. new Point(Width/2+3*arrow_h/2,Height/2+3*arrow_h/2),
  339. new Point(Width/2+arrow_h,Height/2+3*arrow_h/2),
  340. new Point(Width/2+arrow_h,Height/2+arrow_h/2-1),
  341. new Point(Width/2,Height/2+arrow_h/2-1),
  342. new Point(Width/2,Height/2+3*arrow_h/2),
  343. new Point(Width/2-arrow_h/2,Height/2+3*arrow_h/2),
  344. new Point(Width/2+arrow_h/2,Height/2+5*arrow_h/2)
  345. };
  346. break;
  347. case ArrowDirection.DownLeft:
  348. arrow_h = Math.Min(Width / 5, Height / 3);
  349. ps = new Point[]
  350. {
  351. new Point(Width/2-5*arrow_h/2,Height/2+arrow_h/2),
  352. new Point(Width/2-3*arrow_h/2,Height/2+3*arrow_h/2),
  353. new Point(Width/2-3*arrow_h/2,Height/2+arrow_h),
  354. new Point(Width/2-arrow_h/2+1,Height/2+arrow_h),
  355. new Point(Width/2-arrow_h/2+1,Height/2),
  356. new Point(Width/2-3*arrow_h/2,Height/2),
  357. new Point(Width/2-3*arrow_h/2,Height/2-arrow_h/2),
  358. new Point(Width/2-5*arrow_h/2,Height/2+arrow_h/2)
  359. };
  360. break;
  361. case ArrowDirection.DownRight:
  362. arrow_h = Math.Min(Width / 5, Height / 3);
  363. ps = new Point[]
  364. {
  365. new Point(Width/2+5*arrow_h/2,Height/2+arrow_h/2),
  366. new Point(Width/2+3*arrow_h/2,Height/2+3*arrow_h/2),
  367. new Point(Width/2+3*arrow_h/2,Height/2+arrow_h),
  368. new Point(Width/2+arrow_h/2-1,Height/2+arrow_h),
  369. new Point(Width/2+arrow_h/2-1,Height/2),
  370. new Point(Width/2+3*arrow_h/2,Height/2),
  371. new Point(Width/2+3*arrow_h/2,Height/2-arrow_h/2),
  372. new Point(Width/2+5*arrow_h/2,Height/2+arrow_h/2)
  373. };
  374. break;
  375. }
  376. m_path = new GraphicsPath();
  377. m_path.AddLines(ps);
  378. m_path.CloseAllFigures();
  379. }
  380. /// <summary>
  381. /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
  382. /// </summary>
  383. /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
  384. protected override void OnPaint(PaintEventArgs e)
  385. {
  386. base.OnPaint(e);
  387. var g = e.Graphics;
  388. g.SmoothingMode = SmoothingMode.AntiAlias; //使绘图质量最高,即消除锯齿
  389. g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  390. g.CompositingQuality = CompositingQuality.HighQuality;
  391. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
  392. //base.Region = new Region(m_path);
  393. g.FillPath(new SolidBrush(arrowColor), m_path);
  394. if (borderColor != null && borderColor != Color.Empty)
  395. g.DrawPath(new Pen(new SolidBrush(borderColor.Value)), m_path);
  396. if (direction == ArrowDirection.TopRight)
  397. {
  398. int arrow_h = Math.Min(Width / 5, Height / 3);
  399. g.FillPie(new SolidBrush(arrowColor),
  400. new Rectangle((Width - arrow_h)/ 2, Height / 2 - arrow_h, arrow_h * 2+1, arrow_h * 2+1), 180,90);
  401. g.FillRectangle(new SolidBrush(arrowColor),
  402. new RectangleF(new PointF((Width - arrow_h) / 2, Height / 2),new SizeF(arrow_h, Height / 2)));
  403. }
  404. if (direction == ArrowDirection.TopLeft)
  405. {
  406. int arrow_h = Math.Min(Width / 5, Height / 3);
  407. g.FillPie(new SolidBrush(arrowColor),
  408. new Rectangle((Width - 3*arrow_h) / 2, Height / 2 - arrow_h, arrow_h * 2, arrow_h * 2 + 1), 270, 90);
  409. g.FillRectangle(new SolidBrush(arrowColor),
  410. new RectangleF(new PointF((Width - arrow_h) / 2, Height / 2), new SizeF(arrow_h, Height / 2)));
  411. }
  412. if (direction == ArrowDirection.LeftTop)
  413. {
  414. int arrow_h = Math.Min(Width /3, Height / 5);
  415. g.FillPie(new SolidBrush(arrowColor),
  416. new Rectangle(Width / 2 - arrow_h,(Height - 3 * arrow_h) / 2, arrow_h * 2+1, arrow_h * 2), 90, 90);
  417. g.FillRectangle(new SolidBrush(arrowColor),
  418. new RectangleF(new PointF(Width / 2,(Height - arrow_h) / 2), new SizeF(Width / 2,arrow_h)));
  419. }
  420. if (direction == ArrowDirection.LeftDown)
  421. {
  422. int arrow_h = Math.Min(Width / 3, Height / 5);
  423. g.FillPie(new SolidBrush(arrowColor),
  424. new Rectangle(Width / 2 - arrow_h, (Height - arrow_h) / 2, arrow_h * 2+1 , arrow_h * 2), 180, 90);
  425. g.FillRectangle(new SolidBrush(arrowColor),
  426. new RectangleF(new PointF(Width / 2, (Height - arrow_h) / 2), new SizeF(Width / 2, arrow_h)));
  427. }
  428. if (direction == ArrowDirection.RightTop)
  429. {
  430. int arrow_h = Math.Min(Width / 3, Height / 5);
  431. g.FillPie(new SolidBrush(arrowColor),
  432. new Rectangle(Width / 2 - arrow_h, (Height - 3 * arrow_h) / 2, arrow_h * 2 , arrow_h * 2), 0, 90);
  433. g.FillRectangle(new SolidBrush(arrowColor),
  434. new RectangleF(new PointF(0, (Height - arrow_h) / 2), new SizeF(Width / 2+1, arrow_h)));
  435. }
  436. if (direction == ArrowDirection.RightDown)
  437. {
  438. int arrow_h = Math.Min(Width / 3, Height / 5);
  439. g.FillPie(new SolidBrush(arrowColor),
  440. new Rectangle(Width / 2 - arrow_h, (Height - arrow_h+1) / 2, arrow_h * 2, arrow_h * 2), 270, 90);
  441. g.FillRectangle(new SolidBrush(arrowColor),
  442. new RectangleF(new PointF(0, (Height - arrow_h) / 2), new SizeF(Width / 2 + 1, arrow_h)));
  443. }
  444. if (direction == ArrowDirection.DownLeft)
  445. {
  446. int arrow_h = Math.Min(Width / 5, Height / 3);
  447. g.FillPie(new SolidBrush(arrowColor),
  448. new Rectangle((Width - 3 * arrow_h) / 2, Height / 2 - arrow_h, arrow_h * 2, arrow_h * 2 ), 0, 90);
  449. g.FillRectangle(new SolidBrush(arrowColor),
  450. new RectangleF(new PointF((Width - arrow_h) / 2, 0), new SizeF(arrow_h, Height / 2+1)));
  451. }
  452. if (direction == ArrowDirection.DownRight)
  453. {
  454. int arrow_h = Math.Min(Width / 5, Height / 3);
  455. g.FillPie(new SolidBrush(arrowColor),
  456. new Rectangle((Width - arrow_h) / 2, Height / 2 - arrow_h, arrow_h * 2, arrow_h * 2), 90, 90);
  457. g.FillRectangle(new SolidBrush(arrowColor),
  458. new RectangleF(new PointF((Width - arrow_h) / 2, 0), new SizeF(arrow_h, Height / 2 + 1)));
  459. }
  460. if (!string.IsNullOrEmpty(text))
  461. {
  462. var size = g.MeasureString(Text, Font);
  463. g.DrawString(Text, Font, new SolidBrush(ForeColor), new PointF((this.Width - size.Width) / 2, (this.Height - size.Height) / 2));
  464. }
  465. }
  466. }
  467. /// <summary>
  468. /// Enum ArrowDirection
  469. /// </summary>
  470. public enum ArrowDirection
  471. {
  472. /// <summary>
  473. /// The left
  474. /// </summary>
  475. Left,
  476. /// <summary>
  477. /// The right
  478. /// </summary>
  479. Right,
  480. /// <summary>
  481. /// The top
  482. /// </summary>
  483. Top,
  484. /// <summary>
  485. /// The bottom
  486. /// </summary>
  487. Bottom,
  488. /// <summary>
  489. /// The left right
  490. /// </summary>
  491. Left_Right,
  492. /// <summary>
  493. /// The top bottom
  494. /// </summary>
  495. Top_Bottom,
  496. LeftTop,
  497. LeftDown,
  498. RightTop,
  499. RightDown,
  500. TopLeft,
  501. TopRight,
  502. DownLeft,
  503. DownRight
  504. }
  505. }