官网

http://www.hzhcontrols.com

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 

麻烦博客下方点个【推荐】,谢谢

NuGet

  1. Install-Package HZH_Controls

目录

https://www.cnblogs.com/bfyx/p/11364884.html

用处及效果

准备工作

请先了解GDI+和三角函数

开始

添加一个类UCValve,继承UserControl

添加一个阀门显示样式枚举

  1. /// <summary>
  2. /// Enum ValveStyle
  3. /// </summary>
  4. public enum ValveStyle
  5. {
  6. /// <summary>
  7. /// 横向,开关在上方
  8. /// </summary>
  9. Horizontal_Top,
  10. /// <summary>
  11. /// 横向,开关在下方
  12. /// </summary>
  13. Horizontal_Bottom,
  14. /// <summary>
  15. /// 纵向,开关在左侧
  16. /// </summary>
  17. Vertical_Left,
  18. /// <summary>
  19. /// 纵向,开关在右侧
  20. /// </summary>
  21. Vertical_Right,
  22. }

添加一些属性

  1. /// <summary>
  2. /// The valve style
  3. /// </summary>
  4. private ValveStyle valveStyle = ValveStyle.Horizontal_Top;
  5.  
  6. /// <summary>
  7. /// Gets or sets the valve style.
  8. /// </summary>
  9. /// <value>The valve style.</value>
  10. [Description("阀门样式"), Category("自定义")]
  11. public ValveStyle ValveStyle
  12. {
  13. get { return valveStyle; }
  14. set
  15. {
  16. valveStyle = value;
  17. Refresh();
  18. }
  19. }
  20.  
  21. /// <summary>
  22. /// The valve color
  23. /// </summary>
  24. private Color valveColor = Color.FromArgb(, , );
  25.  
  26. /// <summary>
  27. /// Gets or sets the color of the valve.
  28. /// </summary>
  29. /// <value>The color of the valve.</value>
  30. [Description("阀门颜色"), Category("自定义")]
  31. public Color ValveColor
  32. {
  33. get { return valveColor; }
  34. set
  35. {
  36. valveColor = value;
  37. Refresh();
  38. }
  39. }
  40.  
  41. /// <summary>
  42. /// The switch color
  43. /// </summary>
  44. private Color switchColor = Color.FromArgb(, , );
  45.  
  46. /// <summary>
  47. /// Gets or sets the color of the switch.
  48. /// </summary>
  49. /// <value>The color of the switch.</value>
  50. [Description("开关把手颜色"), Category("自定义")]
  51. public Color SwitchColor
  52. {
  53. get { return switchColor; }
  54. set
  55. {
  56. switchColor = value;
  57. Refresh();
  58. }
  59. }
  60.  
  61. /// <summary>
  62. /// The axis color
  63. /// </summary>
  64. private Color axisColor = Color.FromArgb(, , );
  65.  
  66. /// <summary>
  67. /// Gets or sets the color of the axis.
  68. /// </summary>
  69. /// <value>The color of the axis.</value>
  70. [Description("轴颜色"), Category("自定义")]
  71. public Color AxisColor
  72. {
  73. get { return axisColor; }
  74. set
  75. {
  76. axisColor = value;
  77. Refresh();
  78. }
  79. }
  80.  
  81. /// <summary>
  82. /// The asis bottom color
  83. /// </summary>
  84. private Color asisBottomColor = Color.FromArgb(, , );
  85.  
  86. /// <summary>
  87. /// Gets or sets the color of the asis bottom.
  88. /// </summary>
  89. /// <value>The color of the asis bottom.</value>
  90. [Description("轴底座颜色"), Category("自定义")]
  91. public Color AsisBottomColor
  92. {
  93. get { return asisBottomColor; }
  94. set { asisBottomColor = value; }
  95. }
  96.  
  97. /// <summary>
  98. /// The opened
  99. /// </summary>
  100. private bool opened = true;
  101.  
  102. /// <summary>
  103. /// Gets or sets a value indicating whether this <see cref="UCValve" /> is opened.
  104. /// </summary>
  105. /// <value><c>true</c> if opened; otherwise, <c>false</c>.</value>
  106. [Description("是否打开"), Category("自定义")]
  107. public bool Opened
  108. {
  109. get { return opened; }
  110. set
  111. {
  112. opened = value;
  113. Refresh();
  114. }
  115. }
  116.  
  117. /// <summary>
  118. /// The liquid direction
  119. /// </summary>
  120. private LiquidDirection liquidDirection = LiquidDirection.Forward;
  121.  
  122. /// <summary>
  123. /// Gets or sets the liquid direction.
  124. /// </summary>
  125. /// <value>The liquid direction.</value>
  126. [Description("液体流动方向"), Category("自定义")]
  127. public LiquidDirection LiquidDirection
  128. {
  129. get { return liquidDirection; }
  130. set
  131. {
  132. liquidDirection = value;
  133. if (value == Conduit.LiquidDirection.None)
  134. m_timer.Enabled = false;
  135. else
  136. m_timer.Enabled = true;
  137. Refresh();
  138. }
  139. }
  140.  
  141. /// <summary>
  142. /// The liquid speed
  143. /// </summary>
  144. private int liquidSpeed = ;
  145.  
  146. /// <summary>
  147. /// 液体流速,越小,速度越快Gets or sets the liquid speed.
  148. /// </summary>
  149. /// <value>The liquid speed.</value>
  150. [Description("液体流速,越小,速度越快"), Category("自定义")]
  151. public int LiquidSpeed
  152. {
  153. get { return liquidSpeed; }
  154. set
  155. {
  156. if (value <= )
  157. return;
  158. liquidSpeed = value;
  159. m_timer.Interval = value;
  160. }
  161. }
  162.  
  163. /// <summary>
  164. /// The liquid color
  165. /// </summary>
  166. private Color liquidColor = Color.FromArgb(, , );
  167.  
  168. /// <summary>
  169. /// Gets or sets the color of the liquid.
  170. /// </summary>
  171. /// <value>The color of the liquid.</value>
  172. [Description("液体颜色"), Category("自定义")]
  173. public Color LiquidColor
  174. {
  175. get { return liquidColor; }
  176. set
  177. {
  178. liquidColor = value;
  179. if (liquidDirection != Conduit.LiquidDirection.None)
  180. Refresh();
  181. }
  182. }
  183. /// <summary>
  184. /// The m timer
  185. /// </summary>
  186. Timer m_timer;
  187. /// <summary>
  188. /// The int line left
  189. /// </summary>
  190. int intLineLeft = ;

重绘

  1. protected override void OnPaint(PaintEventArgs e)
  2. {
  3. base.OnPaint(e);
  4. var g = e.Graphics;
  5. Rectangle rectGuan = Rectangle.Empty;//管道
  6. Rectangle rectJK1 = Rectangle.Empty;//接口1
  7. Rectangle rectJK2 = Rectangle.Empty;//接口2
  8. Rectangle rectZ = Rectangle.Empty;//轴
  9. GraphicsPath linePath = new GraphicsPath();//管道中心线
  10. GraphicsPath dzPath = new GraphicsPath();//轴底座
  11. GraphicsPath bsPath = new GraphicsPath();//开关把手
  12. switch (valveStyle)
  13. {
  14. case ValveStyle.Horizontal_Top:
  15. rectGuan = new Rectangle(, this.Height / , this.Width, this.Height / - this.Height / );
  16. rectJK1 = new Rectangle(this.Height / , rectGuan.Top - this.Height / , rectGuan.Height / , rectGuan.Height + this.Height / );
  17. rectJK2 = new Rectangle(rectGuan.Right - this.Height / - rectGuan.Height / , rectGuan.Top - this.Height / , rectGuan.Height / , rectGuan.Height + this.Height / );
  18. linePath.AddLine(new Point(rectGuan.Left - , rectGuan.Top + rectGuan.Height / ), new Point(rectGuan.Right + , rectGuan.Top + rectGuan.Height / ));
  19. rectZ = new Rectangle(rectGuan.Left + (rectGuan.Width - rectGuan.Height / ) / , , rectGuan.Height / , rectGuan.Top - );
  20. Point[] psTop = new Point[]
  21. {
  22. new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height/)/,rectGuan.Top- this.Height / - ),
  23. new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height/)/,rectGuan.Top- this.Height / - ),
  24. new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height)/,rectGuan.Top+ ),
  25. new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height)/,rectGuan.Top +),
  26. };
  27. dzPath.AddLines(psTop);
  28. dzPath.CloseAllFigures();
  29. if (opened)
  30. {
  31. bsPath.AddLine(rectGuan.Left + (rectGuan.Width - rectGuan.Height - ) / , + (rectGuan.Height / ) / , rectGuan.Left + (rectGuan.Width - rectGuan.Height - ) / + rectGuan.Height + , + (rectGuan.Height / ) / );
  32. }
  33. else
  34. {
  35. bsPath.AddLine(new Point(rectGuan.Left + rectGuan.Width / - , ), new Point(rectGuan.Left + rectGuan.Width / + , rectGuan.Height + ));
  36. }
  37. break;
  38. case ValveStyle.Horizontal_Bottom:
  39. rectGuan = new Rectangle(, this.Height / , this.Width, this.Height / - this.Height / );
  40. rectJK1 = new Rectangle(this.Height / , rectGuan.Top - this.Height / , rectGuan.Height / , rectGuan.Height + this.Height / );
  41. rectJK2 = new Rectangle(rectGuan.Right - this.Height / - rectGuan.Height / , rectGuan.Top - this.Height / , rectGuan.Height / , rectGuan.Height + this.Height / );
  42. linePath.AddLine(new Point(rectGuan.Left - , rectGuan.Top + rectGuan.Height / ), new Point(rectGuan.Right + , rectGuan.Top + rectGuan.Height / ));
  43. rectZ = new Rectangle(rectGuan.Left + (rectGuan.Width - rectGuan.Height / ) / , rectGuan.Bottom + , rectGuan.Height / , this.Height - - (rectGuan.Bottom + ));
  44. Point[] psBottom = new Point[]
  45. {
  46. new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height/)/,rectGuan.Bottom+ this.Height / + ),
  47. new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height/)/,rectGuan.Bottom+ this.Height / + ),
  48. new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height)/,rectGuan.Bottom- ),
  49. new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height)/,rectGuan.Bottom-),
  50. };
  51. dzPath.AddLines(psBottom);
  52. dzPath.CloseAllFigures();
  53. if (opened)
  54. {
  55. bsPath.AddLine(rectGuan.Left + (rectGuan.Width - rectGuan.Height - ) / , this.Height - ( + (rectGuan.Height / ) / ), rectGuan.Left + (rectGuan.Width - rectGuan.Height - ) / + rectGuan.Height + , this.Height - ( + (rectGuan.Height / ) / ));
  56. }
  57. else
  58. {
  59. bsPath.AddLine(new Point(rectGuan.Left + rectGuan.Width / - , this.Height - ), new Point(rectGuan.Left + rectGuan.Width / + , this.Height - (rectGuan.Height + )));
  60. }
  61. break;
  62. case ValveStyle.Vertical_Left:
  63. rectGuan = new Rectangle(this.Width / , , this.Width / - this.Width / , this.Height);
  64. rectJK1 = new Rectangle(, this.Width / , rectGuan.Width + this.Width / , rectGuan.Width / );
  65. rectJK2 = new Rectangle(, this.Height - this.Width / - rectGuan.Width / , rectGuan.Width + this.Width / , rectGuan.Width / );
  66. linePath.AddLine(new Point(rectGuan.Left + rectGuan.Width / , rectGuan.Top - ), new Point(rectGuan.Left + rectGuan.Width / , rectGuan.Bottom + ));
  67. rectZ = new Rectangle(rectGuan.Right, rectGuan.Top + (rectGuan.Height - rectGuan.Width / ) / , rectGuan.Right - , rectGuan.Width / );
  68. Point[] psLeft = new Point[]
  69. {
  70. new Point(rectGuan.Right+ this.Width / + ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / ) / ),
  71. new Point(rectGuan.Right+ this.Width / + ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / ) / +rectGuan.Width / ),
  72. new Point(rectGuan.Right-, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/+rectGuan.Width),
  73. new Point(rectGuan.Right-, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/),
  74. };
  75. dzPath.AddLines(psLeft);
  76. dzPath.CloseAllFigures();
  77. if (opened)
  78. {
  79. bsPath.AddLine(this.Width - ( + (rectGuan.Width / ) / ), rectGuan.Top + (rectGuan.Height - rectGuan.Width - ) / , this.Width - ( + (rectGuan.Width / ) / ), rectGuan.Top + (rectGuan.Height - rectGuan.Width - ) / + rectGuan.Width + );
  80. }
  81. else
  82. {
  83. bsPath.AddLine(new Point(this.Width - , rectGuan.Top + rectGuan.Height / - ), new Point(this.Width - (rectGuan.Width + ), rectGuan.Top + rectGuan.Height / + ));
  84. }
  85. break;
  86. case ValveStyle.Vertical_Right:
  87. rectGuan = new Rectangle(this.Width - this.Width / - (this.Width / - this.Width / ), , this.Width / - this.Width / , this.Height);
  88. rectJK1 = new Rectangle(this.Width - (rectGuan.Width + this.Width / ), this.Width / , rectGuan.Width + this.Width / , rectGuan.Width / );
  89. rectJK2 = new Rectangle(this.Width - (rectGuan.Width + this.Width / ), this.Height - this.Width / - rectGuan.Width / , rectGuan.Width + this.Width / , rectGuan.Width / );
  90. linePath.AddLine(new Point(rectGuan.Left + rectGuan.Width / , rectGuan.Top - ), new Point(rectGuan.Left + rectGuan.Width / , rectGuan.Bottom + ));
  91. rectZ = new Rectangle(, rectGuan.Top + (rectGuan.Height - rectGuan.Width / ) / , rectGuan.Left-, rectGuan.Width / );
  92. Point[] psRight = new Point[]
  93. {
  94. new Point(rectGuan.Left- (this.Width / + ) ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / ) / ),
  95. new Point(rectGuan.Left-( this.Width / + ) ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / ) / +rectGuan.Width / ),
  96. new Point(rectGuan.Left+, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/+rectGuan.Width),
  97. new Point(rectGuan.Left+, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/),
  98. };
  99. dzPath.AddLines(psRight);
  100. dzPath.CloseAllFigures();
  101.  
  102. if (opened)
  103. {
  104. bsPath.AddLine( ( + (rectGuan.Width / ) / ), rectGuan.Top + (rectGuan.Height - rectGuan.Width - ) / , ( + (rectGuan.Width / ) / ), rectGuan.Top + (rectGuan.Height - rectGuan.Width - ) / + rectGuan.Width + );
  105. }
  106. else
  107. {
  108. bsPath.AddLine(new Point( , rectGuan.Top + rectGuan.Height / - ), new Point( (rectGuan.Width + ), rectGuan.Top + rectGuan.Height / + ));
  109. }
  110. break;
  111. }
  112.  
  113. //管道
  114. g.FillRectangle(new SolidBrush(valveColor), rectGuan);
  115. //接口
  116. g.FillRectangle(new SolidBrush(valveColor), rectJK1);
  117. g.FillRectangle(new SolidBrush(Color.FromArgb(, Color.White)), rectJK1);
  118. g.FillRectangle(new SolidBrush(valveColor), rectJK2);
  119. g.FillRectangle(new SolidBrush(Color.FromArgb(, Color.White)), rectJK2);
  120.  
  121. //高亮
  122. int intCount = (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / / ;
  123. for (int i = ; i < intCount; i++)
  124. {
  125. int _penWidth = (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / - * i;
  126. if (_penWidth <= )
  127. _penWidth = ;
  128. g.DrawPath(new Pen(new SolidBrush(Color.FromArgb(, Color.White.R, Color.White.G, Color.White.B)), _penWidth), linePath);
  129. if (_penWidth == )
  130. break;
  131. }
  132.  
  133. g.SetGDIHigh();
  134. //轴
  135. g.FillRectangle(new SolidBrush(axisColor), rectZ);
  136.  
  137. //阀门底座
  138. g.FillPath(new SolidBrush(asisBottomColor), dzPath);
  139. g.FillPath(new SolidBrush(Color.FromArgb(, Color.White)), dzPath);
  140.  
  141. //把手
  142. g.DrawPath(new Pen(new SolidBrush(switchColor), (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / ), bsPath);
  143.  
  144. //液体流动
  145. if (opened)
  146. {
  147. Pen p = new Pen(new SolidBrush(liquidColor), );
  148. p.DashPattern = new float[] { , };
  149. p.DashOffset = intLineLeft * (LiquidDirection == Conduit.LiquidDirection.Forward ? - : );
  150. g.DrawPath(p, linePath);
  151. }
  152. }

全部代码

  1. // ***********************************************************************
  2. // Assembly : HZH_Controls
  3. // Created : 2019-09-06
  4. //
  5. // ***********************************************************************
  6. // <copyright file="UCValve.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 HZH_Controls.Controls.Conduit;
  24. using System.ComponentModel;
  25.  
  26. namespace HZH_Controls.Controls
  27. {
  28. /// <summary>
  29. /// Class UCValve.
  30. /// Implements the <see cref="System.Windows.Forms.UserControl" />
  31. /// </summary>
  32. /// <seealso cref="System.Windows.Forms.UserControl" />
  33. public class UCValve : UserControl
  34. {
  35. /// <summary>
  36. /// The valve style
  37. /// </summary>
  38. private ValveStyle valveStyle = ValveStyle.Horizontal_Top;
  39.  
  40. /// <summary>
  41. /// Gets or sets the valve style.
  42. /// </summary>
  43. /// <value>The valve style.</value>
  44. [Description("阀门样式"), Category("自定义")]
  45. public ValveStyle ValveStyle
  46. {
  47. get { return valveStyle; }
  48. set
  49. {
  50. valveStyle = value;
  51. Refresh();
  52. }
  53. }
  54.  
  55. /// <summary>
  56. /// The valve color
  57. /// </summary>
  58. private Color valveColor = Color.FromArgb(, , );
  59.  
  60. /// <summary>
  61. /// Gets or sets the color of the valve.
  62. /// </summary>
  63. /// <value>The color of the valve.</value>
  64. [Description("阀门颜色"), Category("自定义")]
  65. public Color ValveColor
  66. {
  67. get { return valveColor; }
  68. set
  69. {
  70. valveColor = value;
  71. Refresh();
  72. }
  73. }
  74.  
  75. /// <summary>
  76. /// The switch color
  77. /// </summary>
  78. private Color switchColor = Color.FromArgb(, , );
  79.  
  80. /// <summary>
  81. /// Gets or sets the color of the switch.
  82. /// </summary>
  83. /// <value>The color of the switch.</value>
  84. [Description("开关把手颜色"), Category("自定义")]
  85. public Color SwitchColor
  86. {
  87. get { return switchColor; }
  88. set
  89. {
  90. switchColor = value;
  91. Refresh();
  92. }
  93. }
  94.  
  95. /// <summary>
  96. /// The axis color
  97. /// </summary>
  98. private Color axisColor = Color.FromArgb(, , );
  99.  
  100. /// <summary>
  101. /// Gets or sets the color of the axis.
  102. /// </summary>
  103. /// <value>The color of the axis.</value>
  104. [Description("轴颜色"), Category("自定义")]
  105. public Color AxisColor
  106. {
  107. get { return axisColor; }
  108. set
  109. {
  110. axisColor = value;
  111. Refresh();
  112. }
  113. }
  114.  
  115. /// <summary>
  116. /// The asis bottom color
  117. /// </summary>
  118. private Color asisBottomColor = Color.FromArgb(, , );
  119.  
  120. /// <summary>
  121. /// Gets or sets the color of the asis bottom.
  122. /// </summary>
  123. /// <value>The color of the asis bottom.</value>
  124. [Description("轴底座颜色"), Category("自定义")]
  125. public Color AsisBottomColor
  126. {
  127. get { return asisBottomColor; }
  128. set { asisBottomColor = value; }
  129. }
  130.  
  131. /// <summary>
  132. /// The opened
  133. /// </summary>
  134. private bool opened = true;
  135.  
  136. /// <summary>
  137. /// Gets or sets a value indicating whether this <see cref="UCValve" /> is opened.
  138. /// </summary>
  139. /// <value><c>true</c> if opened; otherwise, <c>false</c>.</value>
  140. [Description("是否打开"), Category("自定义")]
  141. public bool Opened
  142. {
  143. get { return opened; }
  144. set
  145. {
  146. opened = value;
  147. Refresh();
  148. }
  149. }
  150.  
  151. /// <summary>
  152. /// The liquid direction
  153. /// </summary>
  154. private LiquidDirection liquidDirection = LiquidDirection.Forward;
  155.  
  156. /// <summary>
  157. /// Gets or sets the liquid direction.
  158. /// </summary>
  159. /// <value>The liquid direction.</value>
  160. [Description("液体流动方向"), Category("自定义")]
  161. public LiquidDirection LiquidDirection
  162. {
  163. get { return liquidDirection; }
  164. set
  165. {
  166. liquidDirection = value;
  167. if (value == Conduit.LiquidDirection.None)
  168. m_timer.Enabled = false;
  169. else
  170. m_timer.Enabled = true;
  171. Refresh();
  172. }
  173. }
  174.  
  175. /// <summary>
  176. /// The liquid speed
  177. /// </summary>
  178. private int liquidSpeed = ;
  179.  
  180. /// <summary>
  181. /// 液体流速,越小,速度越快Gets or sets the liquid speed.
  182. /// </summary>
  183. /// <value>The liquid speed.</value>
  184. [Description("液体流速,越小,速度越快"), Category("自定义")]
  185. public int LiquidSpeed
  186. {
  187. get { return liquidSpeed; }
  188. set
  189. {
  190. if (value <= )
  191. return;
  192. liquidSpeed = value;
  193. m_timer.Interval = value;
  194. }
  195. }
  196.  
  197. /// <summary>
  198. /// The liquid color
  199. /// </summary>
  200. private Color liquidColor = Color.FromArgb(, , );
  201.  
  202. /// <summary>
  203. /// Gets or sets the color of the liquid.
  204. /// </summary>
  205. /// <value>The color of the liquid.</value>
  206. [Description("液体颜色"), Category("自定义")]
  207. public Color LiquidColor
  208. {
  209. get { return liquidColor; }
  210. set
  211. {
  212. liquidColor = value;
  213. if (liquidDirection != Conduit.LiquidDirection.None)
  214. Refresh();
  215. }
  216. }
  217. /// <summary>
  218. /// The m timer
  219. /// </summary>
  220. Timer m_timer;
  221. /// <summary>
  222. /// The int line left
  223. /// </summary>
  224. int intLineLeft = ;
  225.  
  226. /// <summary>
  227. /// Initializes a new instance of the <see cref="UCValve" /> class.
  228. /// </summary>
  229. public UCValve()
  230. {
  231. this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
  232. this.SetStyle(ControlStyles.DoubleBuffer, true);
  233. this.SetStyle(ControlStyles.ResizeRedraw, true);
  234. this.SetStyle(ControlStyles.Selectable, true);
  235. this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
  236. this.SetStyle(ControlStyles.UserPaint, true);
  237. this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
  238. this.Size = new Size(, );
  239. m_timer = new Timer();
  240. m_timer.Interval = ;
  241. m_timer.Tick += timer_Tick;
  242. m_timer.Enabled = true;
  243. }
  244.  
  245. /// <summary>
  246. /// Handles the Tick event of the timer control.
  247. /// </summary>
  248. /// <param name="sender">The source of the event.</param>
  249. /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
  250. void timer_Tick(object sender, EventArgs e)
  251. {
  252. intLineLeft += ;
  253. if (intLineLeft > )
  254. intLineLeft = ;
  255. Refresh();
  256. }
  257.  
  258. /// <summary>
  259. /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
  260. /// </summary>
  261. /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
  262. protected override void OnPaint(PaintEventArgs e)
  263. {
  264. base.OnPaint(e);
  265. var g = e.Graphics;
  266. Rectangle rectGuan = Rectangle.Empty;//管道
  267. Rectangle rectJK1 = Rectangle.Empty;//接口1
  268. Rectangle rectJK2 = Rectangle.Empty;//接口2
  269. Rectangle rectZ = Rectangle.Empty;//轴
  270. GraphicsPath linePath = new GraphicsPath();//管道中心线
  271. GraphicsPath dzPath = new GraphicsPath();//轴底座
  272. GraphicsPath bsPath = new GraphicsPath();//开关把手
  273. switch (valveStyle)
  274. {
  275. case ValveStyle.Horizontal_Top:
  276. rectGuan = new Rectangle(, this.Height / , this.Width, this.Height / - this.Height / );
  277. rectJK1 = new Rectangle(this.Height / , rectGuan.Top - this.Height / , rectGuan.Height / , rectGuan.Height + this.Height / );
  278. rectJK2 = new Rectangle(rectGuan.Right - this.Height / - rectGuan.Height / , rectGuan.Top - this.Height / , rectGuan.Height / , rectGuan.Height + this.Height / );
  279. linePath.AddLine(new Point(rectGuan.Left - , rectGuan.Top + rectGuan.Height / ), new Point(rectGuan.Right + , rectGuan.Top + rectGuan.Height / ));
  280. rectZ = new Rectangle(rectGuan.Left + (rectGuan.Width - rectGuan.Height / ) / , , rectGuan.Height / , rectGuan.Top - );
  281. Point[] psTop = new Point[]
  282. {
  283. new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height/)/,rectGuan.Top- this.Height / - ),
  284. new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height/)/,rectGuan.Top- this.Height / - ),
  285. new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height)/,rectGuan.Top+ ),
  286. new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height)/,rectGuan.Top +),
  287. };
  288. dzPath.AddLines(psTop);
  289. dzPath.CloseAllFigures();
  290. if (opened)
  291. {
  292. bsPath.AddLine(rectGuan.Left + (rectGuan.Width - rectGuan.Height - ) / , + (rectGuan.Height / ) / , rectGuan.Left + (rectGuan.Width - rectGuan.Height - ) / + rectGuan.Height + , + (rectGuan.Height / ) / );
  293. }
  294. else
  295. {
  296. bsPath.AddLine(new Point(rectGuan.Left + rectGuan.Width / - , ), new Point(rectGuan.Left + rectGuan.Width / + , rectGuan.Height + ));
  297. }
  298. break;
  299. case ValveStyle.Horizontal_Bottom:
  300. rectGuan = new Rectangle(, this.Height / , this.Width, this.Height / - this.Height / );
  301. rectJK1 = new Rectangle(this.Height / , rectGuan.Top - this.Height / , rectGuan.Height / , rectGuan.Height + this.Height / );
  302. rectJK2 = new Rectangle(rectGuan.Right - this.Height / - rectGuan.Height / , rectGuan.Top - this.Height / , rectGuan.Height / , rectGuan.Height + this.Height / );
  303. linePath.AddLine(new Point(rectGuan.Left - , rectGuan.Top + rectGuan.Height / ), new Point(rectGuan.Right + , rectGuan.Top + rectGuan.Height / ));
  304. rectZ = new Rectangle(rectGuan.Left + (rectGuan.Width - rectGuan.Height / ) / , rectGuan.Bottom + , rectGuan.Height / , this.Height - - (rectGuan.Bottom + ));
  305. Point[] psBottom = new Point[]
  306. {
  307. new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height/)/,rectGuan.Bottom+ this.Height / + ),
  308. new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height/)/,rectGuan.Bottom+ this.Height / + ),
  309. new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height)/,rectGuan.Bottom- ),
  310. new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height)/,rectGuan.Bottom-),
  311. };
  312. dzPath.AddLines(psBottom);
  313. dzPath.CloseAllFigures();
  314. if (opened)
  315. {
  316. bsPath.AddLine(rectGuan.Left + (rectGuan.Width - rectGuan.Height - ) / , this.Height - ( + (rectGuan.Height / ) / ), rectGuan.Left + (rectGuan.Width - rectGuan.Height - ) / + rectGuan.Height + , this.Height - ( + (rectGuan.Height / ) / ));
  317. }
  318. else
  319. {
  320. bsPath.AddLine(new Point(rectGuan.Left + rectGuan.Width / - , this.Height - ), new Point(rectGuan.Left + rectGuan.Width / + , this.Height - (rectGuan.Height + )));
  321. }
  322. break;
  323. case ValveStyle.Vertical_Left:
  324. rectGuan = new Rectangle(this.Width / , , this.Width / - this.Width / , this.Height);
  325. rectJK1 = new Rectangle(, this.Width / , rectGuan.Width + this.Width / , rectGuan.Width / );
  326. rectJK2 = new Rectangle(, this.Height - this.Width / - rectGuan.Width / , rectGuan.Width + this.Width / , rectGuan.Width / );
  327. linePath.AddLine(new Point(rectGuan.Left + rectGuan.Width / , rectGuan.Top - ), new Point(rectGuan.Left + rectGuan.Width / , rectGuan.Bottom + ));
  328. rectZ = new Rectangle(rectGuan.Right, rectGuan.Top + (rectGuan.Height - rectGuan.Width / ) / , rectGuan.Right - , rectGuan.Width / );
  329. Point[] psLeft = new Point[]
  330. {
  331. new Point(rectGuan.Right+ this.Width / + ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / ) / ),
  332. new Point(rectGuan.Right+ this.Width / + ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / ) / +rectGuan.Width / ),
  333. new Point(rectGuan.Right-, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/+rectGuan.Width),
  334. new Point(rectGuan.Right-, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/),
  335. };
  336. dzPath.AddLines(psLeft);
  337. dzPath.CloseAllFigures();
  338. if (opened)
  339. {
  340. bsPath.AddLine(this.Width - ( + (rectGuan.Width / ) / ), rectGuan.Top + (rectGuan.Height - rectGuan.Width - ) / , this.Width - ( + (rectGuan.Width / ) / ), rectGuan.Top + (rectGuan.Height - rectGuan.Width - ) / + rectGuan.Width + );
  341. }
  342. else
  343. {
  344. bsPath.AddLine(new Point(this.Width - , rectGuan.Top + rectGuan.Height / - ), new Point(this.Width - (rectGuan.Width + ), rectGuan.Top + rectGuan.Height / + ));
  345. }
  346. break;
  347. case ValveStyle.Vertical_Right:
  348. rectGuan = new Rectangle(this.Width - this.Width / - (this.Width / - this.Width / ), , this.Width / - this.Width / , this.Height);
  349. rectJK1 = new Rectangle(this.Width - (rectGuan.Width + this.Width / ), this.Width / , rectGuan.Width + this.Width / , rectGuan.Width / );
  350. rectJK2 = new Rectangle(this.Width - (rectGuan.Width + this.Width / ), this.Height - this.Width / - rectGuan.Width / , rectGuan.Width + this.Width / , rectGuan.Width / );
  351. linePath.AddLine(new Point(rectGuan.Left + rectGuan.Width / , rectGuan.Top - ), new Point(rectGuan.Left + rectGuan.Width / , rectGuan.Bottom + ));
  352. rectZ = new Rectangle(, rectGuan.Top + (rectGuan.Height - rectGuan.Width / ) / , rectGuan.Left-, rectGuan.Width / );
  353. Point[] psRight = new Point[]
  354. {
  355. new Point(rectGuan.Left- (this.Width / + ) ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / ) / ),
  356. new Point(rectGuan.Left-( this.Width / + ) ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / ) / +rectGuan.Width / ),
  357. new Point(rectGuan.Left+, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/+rectGuan.Width),
  358. new Point(rectGuan.Left+, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/),
  359. };
  360. dzPath.AddLines(psRight);
  361. dzPath.CloseAllFigures();
  362.  
  363. if (opened)
  364. {
  365. bsPath.AddLine( ( + (rectGuan.Width / ) / ), rectGuan.Top + (rectGuan.Height - rectGuan.Width - ) / , ( + (rectGuan.Width / ) / ), rectGuan.Top + (rectGuan.Height - rectGuan.Width - ) / + rectGuan.Width + );
  366. }
  367. else
  368. {
  369. bsPath.AddLine(new Point( , rectGuan.Top + rectGuan.Height / - ), new Point( (rectGuan.Width + ), rectGuan.Top + rectGuan.Height / + ));
  370. }
  371. break;
  372. }
  373.  
  374. //管道
  375. g.FillRectangle(new SolidBrush(valveColor), rectGuan);
  376. //接口
  377. g.FillRectangle(new SolidBrush(valveColor), rectJK1);
  378. g.FillRectangle(new SolidBrush(Color.FromArgb(, Color.White)), rectJK1);
  379. g.FillRectangle(new SolidBrush(valveColor), rectJK2);
  380. g.FillRectangle(new SolidBrush(Color.FromArgb(, Color.White)), rectJK2);
  381.  
  382. //高亮
  383. int intCount = (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / / ;
  384. for (int i = ; i < intCount; i++)
  385. {
  386. int _penWidth = (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / - * i;
  387. if (_penWidth <= )
  388. _penWidth = ;
  389. g.DrawPath(new Pen(new SolidBrush(Color.FromArgb(, Color.White.R, Color.White.G, Color.White.B)), _penWidth), linePath);
  390. if (_penWidth == )
  391. break;
  392. }
  393.  
  394. g.SetGDIHigh();
  395. //轴
  396. g.FillRectangle(new SolidBrush(axisColor), rectZ);
  397.  
  398. //阀门底座
  399. g.FillPath(new SolidBrush(asisBottomColor), dzPath);
  400. g.FillPath(new SolidBrush(Color.FromArgb(, Color.White)), dzPath);
  401.  
  402. //把手
  403. g.DrawPath(new Pen(new SolidBrush(switchColor), (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / ), bsPath);
  404.  
  405. //液体流动
  406. if (opened)
  407. {
  408. Pen p = new Pen(new SolidBrush(liquidColor), );
  409. p.DashPattern = new float[] { , };
  410. p.DashOffset = intLineLeft * (LiquidDirection == Conduit.LiquidDirection.Forward ? - : );
  411. g.DrawPath(p, linePath);
  412. }
  413. }
  414. }
  415.  
  416. /// <summary>
  417. /// Enum ValveStyle
  418. /// </summary>
  419. public enum ValveStyle
  420. {
  421. /// <summary>
  422. /// 横向,开关在上方
  423. /// </summary>
  424. Horizontal_Top,
  425. /// <summary>
  426. /// 横向,开关在下方
  427. /// </summary>
  428. Horizontal_Bottom,
  429. /// <summary>
  430. /// 纵向,开关在左侧
  431. /// </summary>
  432. Vertical_Left,
  433. /// <summary>
  434. /// 纵向,开关在右侧
  435. /// </summary>
  436. Vertical_Right,
  437. }
  438. }

最后的话

如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧

(五十八)c#Winform自定义控件-管道阀门(工业)的更多相关文章

  1. (五十)c#Winform自定义控件-滑块

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  2. (三十)c#Winform自定义控件-文本框(三)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  3. (二十)c#Winform自定义控件-有后退的窗体

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

  4. (六十)c#Winform自定义控件-鼓风机(工业)

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kwwwvagaa/NetWinformControl 码云:ht ...

  5. (八十)c#Winform自定义控件-分割线标签-HZHControls

    官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...

  6. (五十七)c#Winform自定义控件-传送带(工业)-HZHControls

    官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...

  7. Coding and Paper Letter(五十八)

    资源整理. 1 Coding: 1.支持TMS.WMTS标准瓦片下载,支持百度地图瓦片.高德地图瓦片.腾讯地图瓦片.天地图.ArcServer Rest瓦片.ArcServer本地缓存切片.geose ...

  8. .net开发笔记(十八) winform中的等待框

    winform中很多任务是需要在后台线程(或类似)中完成的,也就是说,经常容易涉及到UI界面与后台工作线程之间的交互.比如UI界面控制后台工作的执行(启动.暂停.停止等),后台工作进度在UI界面上的显 ...

  9. (十)c#Winform自定义控件-横向列表

    前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. 开源地址:https://gitee.com/kwwwvagaa/net_winform_custom_control ...

随机推荐

  1. PyCharm字体大小调整

    1.点击左上角File----settings----keymap----------搜索increase,选中,increase font size--------再选择enter mouse sh ...

  2. ASP.NET Core Web Api之JWT刷新Token(三)

    前言 如题,本节我们进入JWT最后一节内容,JWT本质上就是从身份认证服务器获取访问令牌,继而对于用户后续可访问受保护资源,但是关键问题是:访问令牌的生命周期到底设置成多久呢?见过一些使用JWT的童鞋 ...

  3. 4. 源码分析---SOFARPC服务端暴露

    服务端的示例 我们首先贴上我们的服务端的示例: public static void main(String[] args) { ServerConfig serverConfig = new Ser ...

  4. 1. 源码分析---SOFARPC可扩展的机制SPI

    这几天离职在家,正好没事可以疯狂的输出一下,本来想写DUBBO的源码解析的,但是发现写DUBBO源码的太多了,所以找一个写的不那么多的框架,所以就选中SOFARPC这个框架了. SOFARPC是蚂蚁金 ...

  5. MySQL操作命令梳理(2)

    一.表操作 在mysql运维操作中会经常使用到alter这个修改表的命令,alter tables允许修改一个现有表的结构,比如增加或删除列.创造或消去索引.改变现有列的类型.或重新命名列或表本身,也 ...

  6. Intent 使用详解

    极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android Intent 是一个消息传递对象,主要用于组建之间的通讯,例如:启动Activit ...

  7. Mybatis获取代理对象

    mybatis-config.xml里标签可以放置多个environment,这里可以切换test和develop数据源 databaseIdProvider提供多种数据库,在xml映射文件里选择da ...

  8. Vue项目中使用better-scroll

    当 better-scroll 遇见 Vue   在我们日常的移动端项目开发中,处理滚动列表是再常见不过的需求了. 以滴滴为例,可以是这样竖向滚动的列表,如图所示: 也可以是横向滚动的导航栏,如图所示 ...

  9. alluxio2.0特性-预览

    项目地址 https://github.com/Alluxio/alluxio/tree/branch-2.0-preview 2.0版本-构思和设计 支持超大规模数据工作负载 Alluxio作为计算 ...

  10. 弹性盒子---CSS3布局方式

    1.弹性盒子/伸缩盒子 如果要使用弹性盒子属性,首先要将父级元素变成弹性盒子 Flex-direction 设置伸缩盒子的内部元素的排列方式 Row    从左到右安行排列 Column  从上到下按 ...