UCBottle.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. // ***********************************************************************
  2. // Assembly : HZH_Controls
  3. // Created : 2019-09-05
  4. //
  5. // ***********************************************************************
  6. // <copyright file="UCBottle.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.Linq;
  19. using System.Text;
  20. using System.Windows.Forms;
  21. using System.Drawing;
  22. using System.Drawing.Drawing2D;
  23. using System.ComponentModel;
  24. namespace HZH_Controls.Controls
  25. {
  26. /// <summary>
  27. /// Class UCBottle.
  28. /// Implements the <see cref="System.Windows.Forms.UserControl" />
  29. /// </summary>
  30. /// <seealso cref="System.Windows.Forms.UserControl" />
  31. public class UCBottle : UserControl
  32. {
  33. //瓶身区域
  34. /// <summary>
  35. /// The m working rect
  36. /// </summary>
  37. Rectangle m_workingRect;
  38. /// <summary>
  39. /// The title
  40. /// </summary>
  41. string title = "瓶子1";
  42. /// <summary>
  43. /// Gets or sets the title.
  44. /// </summary>
  45. /// <value>The title.</value>
  46. [Description("标题"), Category("自定义")]
  47. public string Title
  48. {
  49. get { return title; }
  50. set
  51. {
  52. title = value;
  53. ResetWorkingRect();
  54. Refresh();
  55. }
  56. }
  57. /// <summary>
  58. /// The bottle color
  59. /// </summary>
  60. private Color bottleColor = Color.FromArgb(255, 77, 59);
  61. /// <summary>
  62. /// Gets or sets the color of the bottle.
  63. /// </summary>
  64. /// <value>The color of the bottle.</value>
  65. [Description("瓶子颜色"), Category("自定义")]
  66. public Color BottleColor
  67. {
  68. get { return bottleColor; }
  69. set
  70. {
  71. bottleColor = value;
  72. Refresh();
  73. }
  74. }
  75. /// <summary>
  76. /// The bottle mouth color
  77. /// </summary>
  78. private Color bottleMouthColor = Color.FromArgb(105, 105, 105);
  79. /// <summary>
  80. /// Gets or sets the color of the bottle mouth.
  81. /// </summary>
  82. /// <value>The color of the bottle mouth.</value>
  83. [Description("瓶口颜色"), Category("自定义")]
  84. public Color BottleMouthColor
  85. {
  86. get { return bottleMouthColor; }
  87. set { bottleMouthColor = value; }
  88. }
  89. /// <summary>
  90. /// The liquid color
  91. /// </summary>
  92. private Color liquidColor = Color.FromArgb(3, 169, 243);
  93. /// <summary>
  94. /// Gets or sets the color of the liquid.
  95. /// </summary>
  96. /// <value>The color of the liquid.</value>
  97. [Description("液体颜色"), Category("自定义")]
  98. public Color LiquidColor
  99. {
  100. get { return liquidColor; }
  101. set
  102. {
  103. liquidColor = value;
  104. Refresh();
  105. }
  106. }
  107. /// <summary>
  108. /// 获取或设置控件显示的文字的字体。
  109. /// </summary>
  110. /// <value>The font.</value>
  111. /// <PermissionSet>
  112. /// <IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
  113. /// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
  114. /// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence" />
  115. /// <IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
  116. /// </PermissionSet>
  117. [Description("文字字体"), Category("自定义")]
  118. public override Font Font
  119. {
  120. get
  121. {
  122. return base.Font;
  123. }
  124. set
  125. {
  126. base.Font = value;
  127. ResetWorkingRect();
  128. Refresh();
  129. }
  130. }
  131. /// <summary>
  132. /// 获取或设置控件的前景色。
  133. /// </summary>
  134. /// <value>The color of the fore.</value>
  135. /// <PermissionSet>
  136. /// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" />
  137. /// </PermissionSet>
  138. [Description("文字颜色"), Category("自定义")]
  139. public override System.Drawing.Color ForeColor
  140. {
  141. get
  142. {
  143. return base.ForeColor;
  144. }
  145. set
  146. {
  147. base.ForeColor = value;
  148. Refresh();
  149. }
  150. }
  151. /// <summary>
  152. /// The maximum value
  153. /// </summary>
  154. private decimal maxValue = 100;
  155. /// <summary>
  156. /// Gets or sets the maximum value.
  157. /// </summary>
  158. /// <value>The maximum value.</value>
  159. [Description("最大值"), Category("自定义")]
  160. public decimal MaxValue
  161. {
  162. get { return maxValue; }
  163. set
  164. {
  165. if (value < m_value)
  166. return;
  167. maxValue = value;
  168. Refresh();
  169. }
  170. }
  171. /// <summary>
  172. /// The m value
  173. /// </summary>
  174. private decimal m_value = 50;
  175. /// <summary>
  176. /// Gets or sets the value.
  177. /// </summary>
  178. /// <value>The value.</value>
  179. [Description("值"), Category("自定义")]
  180. public decimal Value
  181. {
  182. get { return m_value; }
  183. set
  184. {
  185. if (value <= 0 || value > maxValue)
  186. return;
  187. m_value = value;
  188. Refresh();
  189. }
  190. }
  191. /// <summary>
  192. /// The m no
  193. /// </summary>
  194. private string m_NO;
  195. /// <summary>
  196. /// Gets or sets the NO.
  197. /// </summary>
  198. /// <value>The no.</value>
  199. [Description("编号"), Category("自定义")]
  200. public string NO
  201. {
  202. get { return m_NO; }
  203. set
  204. {
  205. m_NO = value;
  206. Refresh();
  207. }
  208. }
  209. /// <summary>
  210. /// Initializes a new instance of the <see cref="UCBottle" /> class.
  211. /// </summary>
  212. public UCBottle()
  213. {
  214. this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  215. this.SetStyle(ControlStyles.DoubleBuffer, true);
  216. this.SetStyle(ControlStyles.ResizeRedraw, true);
  217. this.SetStyle(ControlStyles.Selectable, true);
  218. this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
  219. this.SetStyle(ControlStyles.UserPaint, true);
  220. this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
  221. this.SizeChanged += UCBottle_SizeChanged;
  222. this.Size = new Size(100, 150);
  223. }
  224. /// <summary>
  225. /// Handles the SizeChanged event of the UCBottle control.
  226. /// </summary>
  227. /// <param name="sender">The source of the event.</param>
  228. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  229. void UCBottle_SizeChanged(object sender, EventArgs e)
  230. {
  231. ResetWorkingRect();
  232. }
  233. /// <summary>
  234. /// Resets the working rect.
  235. /// </summary>
  236. private void ResetWorkingRect()
  237. {
  238. var g = this.CreateGraphics();
  239. var size = g.MeasureString(title, Font);
  240. m_workingRect = new Rectangle(0, (int)size.Height + 10, this.Width, this.Height - ((int)size.Height + 10) - 15);
  241. }
  242. /// <summary>
  243. /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
  244. /// </summary>
  245. /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
  246. protected override void OnPaint(PaintEventArgs e)
  247. {
  248. base.OnPaint(e);
  249. var g = e.Graphics;
  250. g.SetGDIHigh();
  251. //写文字
  252. var size = g.MeasureString(title, Font);
  253. g.DrawString(title, Font, new SolidBrush(ForeColor), new PointF((this.Width - size.Width) / 2, 2));
  254. //画空瓶子
  255. GraphicsPath pathPS = new GraphicsPath();
  256. Point[] psPS = new Point[]
  257. {
  258. new Point(m_workingRect.Left, m_workingRect.Top),
  259. new Point(m_workingRect.Right - 1, m_workingRect.Top),
  260. new Point(m_workingRect.Right - 1, m_workingRect.Bottom - 15),
  261. new Point(m_workingRect.Right - 1 - m_workingRect.Width / 4, m_workingRect.Bottom),
  262. new Point(m_workingRect.Left + m_workingRect.Width / 4, m_workingRect.Bottom),
  263. new Point(m_workingRect.Left, m_workingRect.Bottom - 15),
  264. };
  265. pathPS.AddLines(psPS);
  266. pathPS.CloseAllFigures();
  267. g.FillPath(new SolidBrush(bottleColor), pathPS);
  268. //画液体
  269. decimal decYTHeight = (m_value / maxValue) * m_workingRect.Height;
  270. GraphicsPath pathYT = new GraphicsPath();
  271. Rectangle rectYT = Rectangle.Empty;
  272. if (decYTHeight < 15)
  273. {
  274. PointF[] psYT = new PointF[]
  275. {
  276. new PointF((float)(m_workingRect.Left+(15-decYTHeight))+3,(float)(m_workingRect.Bottom-decYTHeight)),
  277. new PointF((float)(m_workingRect.Right-(15-decYTHeight))-3,(float)(m_workingRect.Bottom-decYTHeight)),
  278. new PointF(m_workingRect.Right-1-m_workingRect.Width/4, m_workingRect.Bottom),
  279. new PointF(m_workingRect.Left+m_workingRect.Width/4, m_workingRect.Bottom),
  280. };
  281. pathYT.AddLines(psYT);
  282. pathYT.CloseAllFigures();
  283. rectYT = new Rectangle((m_workingRect.Left + (15 - (int)decYTHeight)) + 3, m_workingRect.Bottom - (int)decYTHeight - 5, m_workingRect.Width - (int)(15 - decYTHeight) * 2 - 8, 10);
  284. }
  285. else
  286. {
  287. PointF[] psYT = new PointF[]
  288. {
  289. new PointF(m_workingRect.Left,(float)(m_workingRect.Bottom-decYTHeight)),
  290. new PointF(m_workingRect.Right-1,(float)(m_workingRect.Bottom-decYTHeight)),
  291. new PointF(m_workingRect.Right-1,m_workingRect.Bottom-15),
  292. new PointF(m_workingRect.Right-1-m_workingRect.Width/4, m_workingRect.Bottom),
  293. new PointF(m_workingRect.Left+m_workingRect.Width/4, m_workingRect.Bottom),
  294. new PointF(m_workingRect.Left,m_workingRect.Bottom-15),
  295. };
  296. pathYT.AddLines(psYT);
  297. pathYT.CloseAllFigures();
  298. rectYT = new Rectangle(m_workingRect.Left, m_workingRect.Bottom - (int)decYTHeight - 5, m_workingRect.Width, 10);
  299. }
  300. g.FillPath(new SolidBrush(liquidColor), pathYT);
  301. g.FillPath(new SolidBrush(Color.FromArgb(50, bottleMouthColor)), pathYT);
  302. //画液体面
  303. g.FillEllipse(new SolidBrush(liquidColor), rectYT);
  304. g.FillEllipse(new SolidBrush(Color.FromArgb(50, Color.White)), rectYT);
  305. //画高亮
  306. int intCount = m_workingRect.Width / 2 / 4;
  307. int intSplit = (255 - 100) / intCount;
  308. for (int i = 0; i < intCount; i++)
  309. {
  310. int _penWidth = m_workingRect.Width / 2 - 4 * i;
  311. if (_penWidth <= 0)
  312. _penWidth = 1;
  313. g.DrawLine(new Pen(new SolidBrush(Color.FromArgb(10, Color.White)), _penWidth), new Point(m_workingRect.Width / 2, m_workingRect.Top), new Point(m_workingRect.Width / 2, m_workingRect.Bottom - 15));
  314. if (_penWidth == 1)
  315. break;
  316. }
  317. //画瓶底
  318. g.FillEllipse(new SolidBrush(bottleColor), new RectangleF(m_workingRect.Left, m_workingRect.Top - 5, m_workingRect.Width - 2, 10));
  319. g.FillEllipse(new SolidBrush(Color.FromArgb(50, Color.White)), new RectangleF(m_workingRect.Left, m_workingRect.Top - 5, m_workingRect.Width - 2, 10));
  320. //画瓶口
  321. g.FillRectangle(new SolidBrush(bottleMouthColor), new Rectangle(m_workingRect.Left + m_workingRect.Width / 4, m_workingRect.Bottom, m_workingRect.Width / 2, 15));
  322. //画瓶颈阴影
  323. GraphicsPath pathPJ = new GraphicsPath();
  324. Point[] psPJ = new Point[]
  325. {
  326. new Point(m_workingRect.Left, m_workingRect.Bottom-15),
  327. new Point(m_workingRect.Right-1, m_workingRect.Bottom-15),
  328. new Point(m_workingRect.Right-1-m_workingRect.Width/4, m_workingRect.Bottom),
  329. new Point(m_workingRect.Left+m_workingRect.Width/4, m_workingRect.Bottom)
  330. };
  331. pathPJ.AddLines(psPJ);
  332. pathPJ.CloseAllFigures();
  333. g.FillPath(new SolidBrush(Color.FromArgb(50, bottleMouthColor)), pathPJ);
  334. //写编号
  335. if (!string.IsNullOrEmpty(m_NO))
  336. {
  337. var nosize = g.MeasureString(m_NO, Font);
  338. g.DrawString(m_NO, Font, new SolidBrush(ForeColor), new PointF((this.Width - nosize.Width) / 2, m_workingRect.Top + 10));
  339. }
  340. }
  341. }
  342. }