(五十八)c#Winform自定义控件-管道阀门(工业) - 冰封一夏
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.
入行已经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
用处及效果
请先了解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 点个星星吧
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK