(五十八)c#Winform自定義控制元件-管道閥門(工業)
阿新 • • 發佈:2019-09-06
前提
入行已經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 }
全部程式碼
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:[email protected] 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(255, 77, 59); 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(232, 30, 99); 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(3, 169, 243); 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(3, 169, 243); 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 = 100; 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 <= 0) 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(3, 169, 243); 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 = 0; 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(120, 100); 239 m_timer = new Timer(); 240 m_timer.Interval = 100; 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 += 2; 253 if (intLineLeft > 12) 254 intLineLeft = 0; 255 Refresh(); 256 } 257 258 259 /// <summary> 260 /// 引發 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。 261 /// </summary> 262 /// <param name="e">包含事件資料的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param> 263 protected override void OnPaint(PaintEventArgs e) 264 { 265 base.OnPaint(e); 266 var g = e.Graphics; 267 Rectangle rectGuan = Rectangle.Empty;//管道 268 Rectangle rectJK1 = Rectangle.Empty;//介面1 269 Rectangle rectJK2 = Rectangle.Empty;//介面2 270 Rectangle rectZ = Rectangle.Empty;//軸 271 GraphicsPath linePath = new GraphicsPath();//管道中心線 272 GraphicsPath dzPath = new GraphicsPath();//軸底座 273 GraphicsPath bsPath = new GraphicsPath();//開關把手 274 switch (valveStyle) 275 { 276 case ValveStyle.Horizontal_Top: 277 rectGuan = new Rectangle(0, this.Height / 2, this.Width, this.Height / 2 - this.Height / 8); 278 rectJK1 = new Rectangle(this.Height / 8, rectGuan.Top - this.Height / 8, rectGuan.Height / 2, rectGuan.Height + this.Height / 4); 279 rectJK2 = new Rectangle(rectGuan.Right - this.Height / 8 - rectGuan.Height / 2, rectGuan.Top - this.Height / 8, rectGuan.Height / 2, rectGuan.Height + this.Height / 4); 280 linePath.AddLine(new Point(rectGuan.Left - 10, rectGuan.Top + rectGuan.Height / 2), new Point(rectGuan.Right + 10, rectGuan.Top + rectGuan.Height / 2)); 281 rectZ = new Rectangle(rectGuan.Left + (rectGuan.Width - rectGuan.Height / 4) / 2, 10, rectGuan.Height / 4, rectGuan.Top - 10); 282 Point[] psTop = new Point[] 283 { 284 new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height/2)/2,rectGuan.Top- this.Height / 8- 5 ), 285 new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height/2)/2,rectGuan.Top- this.Height / 8- 5 ), 286 new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height)/2,rectGuan.Top+2 ), 287 new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height)/2,rectGuan.Top +2), 288 }; 289 dzPath.AddLines(psTop); 290 dzPath.CloseAllFigures(); 291 if (opened) 292 { 293 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); 294 } 295 else 296 { 297 bsPath.AddLine(new Point(rectGuan.Left + rectGuan.Width / 2 - 3, 1), new Point(rectGuan.Left + rectGuan.Width / 2 + 4, rectGuan.Height + 10)); 298 } 299 break; 300 case ValveStyle.Horizontal_Bottom: 301 rectGuan = new Rectangle(0, this.Height / 8, this.Width, this.Height / 2 - this.Height / 8); 302 rectJK1 = new Rectangle(this.Height / 8, rectGuan.Top - this.Height / 8, rectGuan.Height / 2, rectGuan.Height + this.Height / 4); 303 rectJK2 = new Rectangle(rectGuan.Right - this.Height / 8 - rectGuan.Height / 2, rectGuan.Top - this.Height / 8, rectGuan.Height / 2, rectGuan.Height + this.Height / 4); 304 linePath.AddLine(new Point(rectGuan.Left - 10, rectGuan.Top + rectGuan.Height / 2), new Point(rectGuan.Right + 10, rectGuan.Top + rectGuan.Height / 2)); 305 rectZ = new Rectangle(rectGuan.Left + (rectGuan.Width - rectGuan.Height / 4) / 2, rectGuan.Bottom + 10, rectGuan.Height / 4, this.Height - 10 - (rectGuan.Bottom + 10)); 306 Point[] psBottom = new Point[] 307 { 308 new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height/2)/2,rectGuan.Bottom+ this.Height / 8+ 5 ), 309 new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height/2)/2,rectGuan.Bottom+ this.Height / 8+ 5 ), 310 new Point(rectGuan.Right-(rectGuan.Width-rectGuan.Height)/2,rectGuan.Bottom-2 ), 311 new Point(rectGuan.Left+(rectGuan.Width-rectGuan.Height)/2,rectGuan.Bottom-2), 312 }; 313 dzPath.AddLines(psBottom); 314 dzPath.CloseAllFigures(); 315 if (opened) 316 { 317 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)); 318 } 319 else 320 { 321 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))); 322 } 323 break; 324 case ValveStyle.Vertical_Left: 325 rectGuan = new Rectangle(this.Width / 8, 0, this.Width / 2 - this.Width / 8, this.Height); 326 rectJK1 = new Rectangle(0, this.Width / 8, rectGuan.Width + this.Width / 4, rectGuan.Width / 2); 327 rectJK2 = new Rectangle(0, this.Height - this.Width / 8 - rectGuan.Width / 2, rectGuan.Width + this.Width / 4, rectGuan.Width / 2); 328 linePath.AddLine(new Point(rectGuan.Left + rectGuan.Width / 2, rectGuan.Top - 10), new Point(rectGuan.Left + rectGuan.Width / 2, rectGuan.Bottom + 10)); 329 rectZ = new Rectangle(rectGuan.Right, rectGuan.Top + (rectGuan.Height - rectGuan.Width / 4) / 2, rectGuan.Right - 10, rectGuan.Width / 4); 330 Point[] psLeft = new Point[] 331 { 332 new Point(rectGuan.Right+ this.Width / 8+ 5 ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / 2) / 2), 333 new Point(rectGuan.Right+ this.Width / 8+ 5 ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / 2) / 2+rectGuan.Width / 2), 334 new Point(rectGuan.Right-2, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/2+rectGuan.Width), 335 new Point(rectGuan.Right-2, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/2), 336 }; 337 dzPath.AddLines(psLeft); 338 dzPath.CloseAllFigures(); 339 if (opened) 340 { 341 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); 342 } 343 else 344 { 345 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)); 346 } 347 break; 348 case ValveStyle.Vertical_Right: 349 rectGuan = new Rectangle(this.Width - this.Width / 8 - (this.Width / 2 - this.Width / 8), 0, this.Width / 2 - this.Width / 8, this.Height); 350 rectJK1 = new Rectangle(this.Width - (rectGuan.Width + this.Width / 4), this.Width / 8, rectGuan.Width + this.Width / 4, rectGuan.Width / 2); 351 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); 352 linePath.AddLine(new Point(rectGuan.Left + rectGuan.Width / 2, rectGuan.Top - 10), new Point(rectGuan.Left + rectGuan.Width / 2, rectGuan.Bottom + 10)); 353 rectZ = new Rectangle(10, rectGuan.Top + (rectGuan.Height - rectGuan.Width / 4) / 2, rectGuan.Left-10, rectGuan.Width / 4); 354 Point[] psRight = new Point[] 355 { 356 new Point(rectGuan.Left- (this.Width / 8+ 5) ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / 2) / 2), 357 new Point(rectGuan.Left-( this.Width / 8+ 5) ,rectGuan.Top + (rectGuan.Height - rectGuan.Width / 2) / 2+rectGuan.Width / 2), 358 new Point(rectGuan.Left+2, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/2+rectGuan.Width), 359 new Point(rectGuan.Left+2, rectGuan.Top +(rectGuan.Height-rectGuan.Width)/2), 360 }; 361 dzPath.AddLines(psRight); 362 dzPath.CloseAllFigures(); 363 364 if (opened) 365 { 366 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); 367 } 368 else 369 { 370 bsPath.AddLine(new Point( 1, rectGuan.Top + rectGuan.Height / 2 - 3), new Point( (rectGuan.Width + 10), rectGuan.Top + rectGuan.Height / 2 + 4)); 371 } 372 break; 373 } 374 375 //管道 376 g.FillRectangle(new SolidBrush(valveColor), rectGuan); 377 //介面 378 g.FillRectangle(new SolidBrush(valveColor), rectJK1); 379 g.FillRectangle(new SolidBrush(Color.FromArgb(40, Color.White)), rectJK1); 380 g.FillRectangle(new SolidBrush(valveColor), rectJK2); 381 g.FillRectangle(new SolidBrush(Color.FromArgb(40, Color.White)), rectJK2); 382 383 384 //高亮 385 int intCount = (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / 2 / 4; 386 for (int i = 0; i < intCount; i++) 387 { 388 int _penWidth = (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / 2 - 4 * i; 389 if (_penWidth <= 0) 390 _penWidth = 1; 391 g.DrawPath(new Pen(new SolidBrush(Color.FromArgb(40, Color.White.R, Color.White.G, Color.White.B)), _penWidth), linePath); 392 if (_penWidth == 1) 393 break; 394 } 395 396 g.SetGDIHigh(); 397 //軸 398 g.FillRectangle(new SolidBrush(axisColor), rectZ); 399 400 //閥門底座 401 g.FillPath(new SolidBrush(asisBottomColor), dzPath); 402 g.FillPath(new SolidBrush(Color.FromArgb(50, Color.White)), dzPath); 403 404 //把手 405 g.DrawPath(new Pen(new SolidBrush(switchColor), (valveStyle.ToString().StartsWith("H") ? rectGuan.Height : rectGuan.Width) / 3), bsPath); 406 407 //液體流動 408 if (opened) 409 { 410 Pen p = new Pen(new SolidBrush(liquidColor), 4); 411 p.DashPattern = new float[] { 6, 6 }; 412 p.DashOffset = intLineLeft * (LiquidDirection == Conduit.LiquidDirection.Forward ? -1 : 1); 413 g.DrawPath(p, linePath); 414 } 415 } 416 } 417 418 /// <summary> 419 /// Enum ValveStyle 420 /// </summary> 421 public enum ValveStyle 422 { 423 /// <summary> 424 /// 橫向,開關在上方 425 /// </summary> 426 Horizontal_Top, 427 /// <summary> 428 /// 橫向,開關在下方 429 /// </summary> 430 Horizontal_Bottom, 431 /// <summary> 432 /// 縱向,開關在左側 433 /// </summary> 434 Vertical_Left, 435 /// <summary> 436 /// 縱向,開關在右側 437 /// </summary> 438 Vertical_Right, 439 } 440 }View Code
最後的話
如果你喜歡的話,請到 https://gitee.com/kwwwvagaa/net_winform_custom_control 點個星星吧