43

(五十八)c#Winform自定义控件-管道阀门(工业) - 冰封一夏

 4 years ago
source link: https://www.cnblogs.com/bfyx/p/11475709.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

http://www.hzhcontrols.com

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

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

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

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

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

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

NuGet

Install-Package HZH_Controls

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

用处及效果

396919-20190906163739366-973417720.gif

396919-20190906163745375-400720746.gif

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

View Code

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK