1. 程式人生 > >(五十五)c#Winform自定義控制元件-管道

(五十五)c#Winform自定義控制元件-管道

前提

入行已經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+畫的,用到了三角函式,如果不瞭解可以先行百度

開始

新增一個類UCConduit,繼承UserControl

新增幾個屬性

  1 /// <summary>
  2         /// The conduit style
  3         /// </summary>
  4         private ConduitStyle conduitStyle = ConduitStyle.Horizontal_None_None;
  5 
  6         /// <summary>
  7         /// Gets or sets the conduit style.
  8         /// </summary>
  9         /// <value>The conduit style.</value>
 10         [Description("樣式"), Category("自定義")]
 11         public ConduitStyle ConduitStyle
 12         {
 13             get { return conduitStyle; }
 14             set
 15             {
 16                 string strOld = conduitStyle.ToString().Substring(0, 1);
 17                 string strNew = value.ToString().Substring(0, 1);
 18                 conduitStyle = value;
 19                 if (strOld != strNew)
 20                 {
 21                     this.Size = new Size(this.Size.Height, this.Size.Width);
 22                 }
 23                 Refresh();
 24             }
 25         }
 26 
 27         /// <summary>
 28         /// The conduit color
 29         /// </summary>
 30         private Color conduitColor = Color.FromArgb(255, 77, 59);
 31         [Description("顏色"), Category("自定義")]
 32         /// <summary>
 33         /// Gets or sets the color of the conduit.
 34         /// </summary>
 35         /// <value>The color of the conduit.</value>
 36         public Color ConduitColor
 37         {
 38             get { return conduitColor; }
 39             set
 40             {
 41                 conduitColor = value;
 42                 Refresh();
 43             }
 44         }
 45 
 46         /// <summary>
 47         /// The liquid color
 48         /// </summary>
 49         private Color liquidColor = Color.FromArgb(3, 169, 243);
 50 
 51         /// <summary>
 52         /// Gets or sets the color of the liquid.
 53         /// </summary>
 54         /// <value>The color of the liquid.</value>
 55         [Description("液體顏色"), Category("自定義")]
 56         public Color LiquidColor
 57         {
 58             get { return liquidColor; }
 59             set
 60             {
 61                 liquidColor = value;
 62                 if (liquidDirection != Conduit.LiquidDirection.None)
 63                     Refresh();
 64             }
 65         }
 66 
 67         /// <summary>
 68         /// The liquid direction
 69         /// </summary>
 70         private LiquidDirection liquidDirection = LiquidDirection.Forward;
 71 
 72         /// <summary>
 73         /// Gets or sets the liquid direction.
 74         /// </summary>
 75         /// <value>The liquid direction.</value>
 76         [Description("液體流動方向"), Category("自定義")]
 77         public LiquidDirection LiquidDirection
 78         {
 79             get { return liquidDirection; }
 80             set
 81             {
 82                 liquidDirection = value;
 83                 Refresh();
 84             }
 85         }
 86 
 87         /// <summary>
 88         /// The liquid speed
 89         /// </summary>
 90         private int liquidSpeed = 100;
 91 
 92         /// <summary>
 93         /// 液體流速,越小,速度越快Gets or sets the liquid speed.
 94         /// </summary>
 95         /// <value>The liquid speed.</value>
 96         [Description("液體流速,越小,速度越快"), Category("自定義")]
 97         public int LiquidSpeed
 98         {
 99             get { return liquidSpeed; }
100             set
101             {
102                 if (value <= 0)
103                     return;
104                 liquidSpeed = value;
105                 m_timer.Interval = value;
106             }
107         }
108 
109         /// <summary>
110         /// The int pen width
111         /// </summary>
112         int intPenWidth = 0;
113 
114         /// <summary>
115         /// The int line left
116         /// </summary>
117         int intLineLeft = 0;
118         /// <summary>
119         /// The m timer
120         /// </summary>
121         Timer m_timer;

根據引數設定重繪

  1 /// <summary>
  2         /// 引發 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
  3         /// </summary>
  4         /// <param name="e">包含事件資料的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
  5         protected override void OnPaint(PaintEventArgs e)
  6         {
  7             base.OnPaint(e);
  8             Graphics g = e.Graphics;
  9 
 10             List<ArcEntity> lstArcs = new List<ArcEntity>();
 11 
 12             GraphicsPath path = new GraphicsPath();
 13             GraphicsPath linePath = new GraphicsPath();
 14             switch (conduitStyle)
 15             {
 16                 #region H    English:H
 17                 case ConduitStyle.Horizontal_None_None:
 18                     path.AddLines(new PointF[]
 19                     { 
 20                         new PointF(0, 0), 
 21                         new PointF(this.ClientRectangle.Right, 0),
 22                         new PointF(this.ClientRectangle.Right, this.Height),
 23                         new PointF(0, this.Height)
 24                     });
 25                     path.CloseAllFigures();
 26                     linePath.AddLine(0, this.Height / 2, this.Width, this.Height / 2);
 27                     break;
 28                 case ConduitStyle.Horizontal_Up_None:
 29                     path.AddLines(new PointF[]
 30                     { 
 31                         new PointF(0, 0), 
 32                         new PointF(this.ClientRectangle.Right, 0),
 33                         new PointF(this.ClientRectangle.Right, this.Height),
 34                         new PointF(0+intPenWidth, this.Height)
 35                     });
 36                     path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
 37                     path.CloseAllFigures();
 38 
 39                     linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
 40                     linePath.AddLine(intPenWidth, this.Height / 2, this.Width, this.Height / 2);
 41 
 42                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
 43                     break;
 44                 case ConduitStyle.Horizontal_Down_None:
 45                     path.AddLines(new PointF[]
 46                     { 
 47                         new PointF(intPenWidth, 0), 
 48                         new PointF(this.ClientRectangle.Right, 0),
 49                         new PointF(this.ClientRectangle.Right, this.Height),
 50                         new PointF(0, this.Height)
 51                     });
 52                     path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
 53                     path.CloseAllFigures();
 54 
 55                     linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
 56                     linePath.AddLine(intPenWidth + 1, this.Height / 2, this.Width, this.Height / 2);
 57 
 58                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
 59                     break;
 60                 case ConduitStyle.Horizontal_None_Up:
 61                     path.AddLines(new PointF[]
 62                     { 
 63                         new PointF(this.ClientRectangle.Right-intPenWidth, this.Height),
 64                         new PointF(0, this.Height),
 65                         new PointF(0, 0), 
 66                         new PointF(this.ClientRectangle.Right-intPenWidth, 0)
 67                     });
 68                     path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
 69                     path.CloseAllFigures();
 70 
 71                     linePath.AddLine(0, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
 72                     linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
 73 
 74                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
 75                     break;
 76                 case ConduitStyle.Horizontal_None_Down:
 77                     path.AddLines(new PointF[]
 78                     { 
 79                         new PointF(this.ClientRectangle.Right, this.Height),
 80                         new PointF(0, this.Height),
 81                         new PointF(0, 0), 
 82                         new PointF(this.ClientRectangle.Right-intPenWidth, 0)
 83                     });
 84                     path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
 85                     path.CloseAllFigures();
 86 
 87                     linePath.AddLine(0, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
 88                     linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
 89 
 90                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
 91                     break;
 92                 case ConduitStyle.Horizontal_Down_Up:
 93                     path.AddLine(new Point(intPenWidth, 0), new Point(this.Width, 0));
 94                     path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
 95                     path.AddLine(new Point(this.Width - intPenWidth, this.Height), new Point(0, this.Height));
 96                     path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
 97                     path.CloseAllFigures();
 98 
 99                     linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
100                     //linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
101                     linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
102 
103                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
104                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
105                     break;
106                 case ConduitStyle.Horizontal_Up_Down:
107                     path.AddLine(new Point(0, 0), new Point(this.Width - intPenWidth, 0));
108                     path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
109                     path.AddLine(new Point(this.Width, this.Height), new Point(intPenWidth, this.Height));
110                     path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
111                     path.CloseAllFigures();
112 
113                     linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
114                     linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
115                     linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
116 
117                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
118                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
119                     break;
120                 case ConduitStyle.Horizontal_Up_Up:
121                     path.AddLine(new Point(0, 0), new Point(this.Width, 0));
122                     path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
123                     path.AddLine(new Point(this.Width - intPenWidth, this.Height), new Point(intPenWidth, this.Height));
124                     path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
125                     path.CloseAllFigures();
126 
127                     linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
128                     //linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
129                     linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
130 
131                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
132                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
133                     break;
134                 case ConduitStyle.Horizontal_Down_Down:
135                     path.AddLine(new Point(intPenWidth, 0), new Point(this.Width - intPenWidth, 0));
136                     path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
137                     path.AddLine(new Point(this.Width, this.Height), new Point(0, this.Height));
138                     path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
139                     path.CloseAllFigures();
140 
141                     linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
142                     linePath.AddLine(intPenWidth + 1, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
143                     linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
144 
145                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
146                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
147                     break;
148                 #endregion
149 
150                 #region V    English:V
151                 case ConduitStyle.Vertical_None_None:
152                     path.AddLines(new PointF[]
153                     { 
154                         new PointF(0, 0), 
155                         new PointF(this.ClientRectangle.Right, 0),
156                         new PointF(this.ClientRectangle.Right, this.Height),
157                         new PointF(0, this.Height)
158                     });
159                     path.CloseAllFigures();
160                     linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height);
161                     break;
162                 case ConduitStyle.Vertical_Left_None:
163                     path.AddLines(new PointF[]
164                     { 
165                         new PointF(this.ClientRectangle.Right, intPenWidth),
166                         new PointF(this.ClientRectangle.Right, this.Height),
167                         new PointF(0, this.Height),
168                         new PointF(0, 0)
169                     });
170                     path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
171                     path.CloseAllFigures();
172 
173                     linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
174                     linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height);
175 
176                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
177                     break;
178                 case ConduitStyle.Vertical_Right_None:
179                     path.AddLines(new PointF[]
180                     { 
181                         new PointF(this.ClientRectangle.Right, 0),
182                         new PointF(this.ClientRectangle.Right, this.Height),
183                         new PointF(0, this.Height),
184                         new PointF(0, intPenWidth)
185                     });
186                     path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
187                     path.CloseAllFigures();
188 
189                     linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
190                     linePath.AddLine(intPenWidth / 2, intPenWidth + 1, intPenWidth / 2, this.Height);
191 
192                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
193                     break;
194                 case ConduitStyle.Vertical_None_Left:
195                     path.AddLines(new PointF[]
196                     { 
197                         new PointF(0, this.Height),
198                         new PointF(0, 0),
199                         new PointF(this.ClientRectangle.Right, 0),
200                         new PointF(this.ClientRectangle.Right, this.Height-intPenWidth),
201                     });
202                     path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
203                     path.CloseAllFigures();
204 
205                     linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height - intPenWidth);
206                     linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
207 
208                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
209                     break;
210                 case ConduitStyle.Vertical_None_Right:
211                     path.AddLines(new PointF[]
212                     { 
213                         new PointF(0, this.Height-intPenWidth),
214                         new PointF(0, 0),
215                         new PointF(this.ClientRectangle.Right, 0),
216                         new PointF(this.ClientRectangle.Right, this.Height),
217                     });
218                     path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
219                     path.CloseAllFigures();
220 
221                     linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height - intPenWidth - 1);
222                     linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
223 
224                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
225                     break;
226                 case ConduitStyle.Vertical_Left_Right:
227                     path.AddLine(this.Width, intPenWidth, this.Width, this.Height);
228                     path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
229                     path.AddLine(0, this.Height - intPenWidth, 0, 0);
230                     path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
231                     path.CloseAllFigures();
232 
233                     linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
234                     //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
235                     linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
236 
237                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
238                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
239                     break;
240                 case ConduitStyle.Vertical_Right_Left:
241                     path.AddLine(this.Width, 0, this.Width, this.Height - intPenWidth);
242                     path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
243                     path.AddLine(0, this.Height, 0, intPenWidth);
244                     path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
245                     path.CloseAllFigures();
246 
247                     linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
248                     //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
249                     linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
250 
251                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
252                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
253                     break;
254                 case ConduitStyle.Vertical_Left_Left:
255                     path.AddLine(this.Width, intPenWidth, this.Width, this.Height - intPenWidth);
256                     path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
257                     path.AddLine(0, this.Height, 0, 0);
258                     path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
259                     path.CloseAllFigures();
260 
261                     linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
262                     //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
263                     linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
264 
265                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
266                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
267                     break;
268                 case ConduitStyle.Vertical_Right_Right:
269                     path.AddLine(this.Width, 0, this.Width, this.Height);
270                     path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
271                     path.AddLine(0, this.Height - intPenWidth, 0, intPenWidth);
272                     path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
273                     path.CloseAllFigures();
274 
275                     linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
276                     //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
277                     linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 180, -91);
278 
279                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
280                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
281                     break;
282                 #endregion
283             }
284             g.FillPath(new SolidBrush(conduitColor), path);
285 
286             //漸變色
287             int intCount = intPenWidth / 2 / 4;
288             int intSplit = (255 - 100) / intCount;
289             for (int i = 0; i < intCount; i++)
290             {
291                 int _penWidth = intPenWidth / 2 - 4 * i;
292                 if (_penWidth <= 0)
293                     _penWidth = 1;
294                 g.DrawPath(new Pen(new SolidBrush(Color.FromArgb(40, Color.White.R, Color.White.G, Color.White.B)), _penWidth), linePath);
295                 if (_penWidth == 1)
296                     break;
297             }
298 
299             g.SetGDIHigh();
300             //使用抗鋸齒畫圓角
301             foreach (var item in lstArcs)
302             {
303                 g.DrawArc(new Pen(new SolidBrush(this.BackColor)), item.rect, item.startAngle, item.sweepAngle);
304             }
305 
306             //液體流動
307             if (LiquidDirection != Conduit.LiquidDirection.None)
308             {
309                 Pen p = new Pen(new SolidBrush(liquidColor), 4);
310                 p.DashPattern = new float[] { 6, 6 };
311                 p.DashOffset = intLineLeft * (LiquidDirection == Conduit.LiquidDirection.Forward ? -1 : 1);
312                 g.DrawPath(p, linePath);
313             }
314         }

一個記錄圓角的類

 1  /// <summary>
 2         /// Class ArcEntity.
 3         /// </summary>
 4         class ArcEntity
 5         {
 6             /// <summary>
 7             /// Gets or sets the rect.
 8             /// </summary>
 9             /// <value>The rect.</value>
10             public Rectangle rect { get; set; }
11             /// <summary>
12             /// Gets or sets the start angle.
13             /// </summary>
14             /// <value>The start angle.</value>
15             public float startAngle { get; set; }
16             /// <summary>
17             /// Gets or sets the sweep angle.
18             /// </summary>
19             /// <value>The sweep angle.</value>
20             public float sweepAngle { get; set; }
21         }

2個列舉

 1 /// <summary>
 2     /// Enum LiquidDirection
 3     /// </summary>
 4     public enum LiquidDirection
 5     {
 6         /// <summary>
 7         /// The none
 8         /// </summary>
 9         None,
10         /// <summary>
11         /// The forward
12         /// </summary>
13         Forward,
14         /// <summary>
15         /// The backward
16         /// </summary>
17         Backward
18     }
19 
20     /// <summary>
21     /// 管道樣式Enum ConduitStyle
22     /// </summary>
23     public enum ConduitStyle
24     {
25         /// <summary>
26         /// 直線 The horizontal none none
27         /// </summary>
28         Horizontal_None_None,
29         /// <summary>
30         /// 左上The horizontal up none
31         /// </summary>
32         Horizontal_Up_None,
33         /// <summary>
34         /// 左下The horizontal down none
35         /// </summary>
36         Horizontal_Down_None,
37         /// <summary>
38         /// 右上The horizontal none up
39         /// </summary>
40         Horizontal_None_Up,
41         /// <summary>
42         /// 右下The horizontal none down
43         /// </summary>
44         Horizontal_None_Down,
45         /// <summary>
46         /// 左下右上The horizontal down up
47         /// </summary>
48         Horizontal_Down_Up,
49         /// <summary>
50         /// 左上右下The horizontal up down
51         /// </summary>
52         Horizontal_Up_Down,
53         /// <summary>
54         /// 左上,右上The horizontal up up
55         /// </summary>
56         Horizontal_Up_Up,
57         /// <summary>
58         /// 左下右下The horizontal down down
59         /// </summary>
60         Horizontal_Down_Down,
61 
62         /// <summary>
63         /// 豎線The vertical none none
64         /// </summary>
65         Vertical_None_None,
66         /// <summary>
67         /// 上左The vertical left none
68         /// </summary>
69         Vertical_Left_None,
70         /// <summary>
71         /// 上右The vertical right none
72         /// </summary>
73         Vertical_Right_None,
74         /// <summary>
75         /// 下左The vertical none left
76         /// </summary>
77         Vertical_None_Left,
78         /// <summary>
79         /// 下右The vertical none right
80         /// </summary>
81         Vertical_None_Right,
82         /// <summary>
83         /// 上左下右The vertical left right
84         /// </summary>
85         Vertical_Left_Right,
86         /// <summary>
87         /// 上右下左The vertical right left
88         /// </summary>
89         Vertical_Right_Left,
90         /// <summary>
91         /// 上左下左The vertical left left
92         /// </summary>
93         Vertical_Left_Left,
94         /// <summary>
95         /// 上右下右The vertical right left
96         /// </summary>
97         Vertical_Right_Right,
98     }

重點講解來了,

重繪的時候,先填充底色,並且記錄下中心線path,和圓角

填充底色後,畫中間的漸變色

然後設定g為抗鋸齒模式,把圓角重畫一遍,就沒有鋸齒感了

然後根據中心線,畫液體就可以了

完整程式碼

  1 // ***********************************************************************
  2 // Assembly         : HZH_Controls
  3 // Created          : 2019-09-04
  4 //
  5 // ***********************************************************************
  6 // <copyright file="UCConduit.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 System.ComponentModel;
 24 
 25 namespace HZH_Controls.Controls.Conduit
 26 {
 27     /// <summary>
 28     /// Class UCConduit.
 29     /// Implements the <see cref="System.Windows.Forms.UserControl" />
 30     /// </summary>
 31     /// <seealso cref="System.Windows.Forms.UserControl" />
 32     public class UCConduit : UserControl
 33     {
 34         /// <summary>
 35         /// The conduit style
 36         /// </summary>
 37         private ConduitStyle conduitStyle = ConduitStyle.Horizontal_None_None;
 38 
 39         /// <summary>
 40         /// Gets or sets the conduit style.
 41         /// </summary>
 42         /// <value>The conduit style.</value>
 43         [Description("樣式"), Category("自定義")]
 44         public ConduitStyle ConduitStyle
 45         {
 46             get { return conduitStyle; }
 47             set
 48             {
 49                 string strOld = conduitStyle.ToString().Substring(0, 1);
 50                 string strNew = value.ToString().Substring(0, 1);
 51                 conduitStyle = value;
 52                 if (strOld != strNew)
 53                 {
 54                     this.Size = new Size(this.Size.Height, this.Size.Width);
 55                 }
 56                 Refresh();
 57             }
 58         }
 59 
 60         /// <summary>
 61         /// The conduit color
 62         /// </summary>
 63         private Color conduitColor = Color.FromArgb(255, 77, 59);
 64         [Description("顏色"), Category("自定義")]
 65         /// <summary>
 66         /// Gets or sets the color of the conduit.
 67         /// </summary>
 68         /// <value>The color of the conduit.</value>
 69         public Color ConduitColor
 70         {
 71             get { return conduitColor; }
 72             set
 73             {
 74                 conduitColor = value;
 75                 Refresh();
 76             }
 77         }
 78 
 79         /// <summary>
 80         /// The liquid color
 81         /// </summary>
 82         private Color liquidColor = Color.FromArgb(3, 169, 243);
 83 
 84         /// <summary>
 85         /// Gets or sets the color of the liquid.
 86         /// </summary>
 87         /// <value>The color of the liquid.</value>
 88         [Description("液體顏色"), Category("自定義")]
 89         public Color LiquidColor
 90         {
 91             get { return liquidColor; }
 92             set
 93             {
 94                 liquidColor = value;
 95                 if (liquidDirection != Conduit.LiquidDirection.None)
 96                     Refresh();
 97             }
 98         }
 99 
100         /// <summary>
101         /// The liquid direction
102         /// </summary>
103         private LiquidDirection liquidDirection = LiquidDirection.Forward;
104 
105         /// <summary>
106         /// Gets or sets the liquid direction.
107         /// </summary>
108         /// <value>The liquid direction.</value>
109         [Description("液體流動方向"), Category("自定義")]
110         public LiquidDirection LiquidDirection
111         {
112             get { return liquidDirection; }
113             set
114             {
115                 liquidDirection = value;
116                 Refresh();
117             }
118         }
119 
120         /// <summary>
121         /// The liquid speed
122         /// </summary>
123         private int liquidSpeed = 100;
124 
125         /// <summary>
126         /// 液體流速,越小,速度越快Gets or sets the liquid speed.
127         /// </summary>
128         /// <value>The liquid speed.</value>
129         [Description("液體流速,越小,速度越快"), Category("自定義")]
130         public int LiquidSpeed
131         {
132             get { return liquidSpeed; }
133             set
134             {
135                 if (value <= 0)
136                     return;
137                 liquidSpeed = value;
138                 m_timer.Interval = value;
139             }
140         }
141 
142         /// <summary>
143         /// The int pen width
144         /// </summary>
145         int intPenWidth = 0;
146 
147         /// <summary>
148         /// The int line left
149         /// </summary>
150         int intLineLeft = 0;
151         /// <summary>
152         /// The m timer
153         /// </summary>
154         Timer m_timer;
155         /// <summary>
156         /// Initializes a new instance of the <see cref="UCConduit"/> class.
157         /// </summary>
158         public UCConduit()
159         {
160             this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
161             this.SetStyle(ControlStyles.DoubleBuffer, true);
162             this.SetStyle(ControlStyles.ResizeRedraw, true);
163             this.SetStyle(ControlStyles.Selectable, true);
164             this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
165             this.SetStyle(ControlStyles.UserPaint, true);
166             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
167             this.SizeChanged += UCConduit_SizeChanged;
168             this.Size = new Size(200, 50);
169             m_timer = new Timer();
170             m_timer.Interval = 100;
171             m_timer.Tick += timer_Tick;
172             m_timer.Enabled = true;
173         }
174 
175         /// <summary>
176         /// Handles the Tick event of the timer control.
177         /// </summary>
178         /// <param name="sender">The source of the event.</param>
179         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
180         void timer_Tick(object sender, EventArgs e)
181         {
182             intLineLeft += 2;
183             if (intLineLeft > 12)
184                 intLineLeft = 0;
185             Refresh();
186         }
187 
188 
189         /// <summary>
190         /// Handles the SizeChanged event of the UCConduit control.
191         /// </summary>
192         /// <param name="sender">The source of the event.</param>
193         /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
194         void UCConduit_SizeChanged(object sender, EventArgs e)
195         {
196             intPenWidth = conduitStyle.ToString().StartsWith("H") ? this.Height : this.Width;
197         }
198 
199         /// <summary>
200         /// 引發 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
201         /// </summary>
202         /// <param name="e">包含事件資料的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
203         protected override void OnPaint(PaintEventArgs e)
204         {
205             base.OnPaint(e);
206             Graphics g = e.Graphics;
207 
208             List<ArcEntity> lstArcs = new List<ArcEntity>();
209 
210             GraphicsPath path = new GraphicsPath();
211             GraphicsPath linePath = new GraphicsPath();
212             switch (conduitStyle)
213             {
214                 #region H    English:H
215                 case ConduitStyle.Horizontal_None_None:
216                     path.AddLines(new PointF[]
217                     { 
218                         new PointF(0, 0), 
219                         new PointF(this.ClientRectangle.Right, 0),
220                         new PointF(this.ClientRectangle.Right, this.Height),
221                         new PointF(0, this.Height)
222                     });
223                     path.CloseAllFigures();
224                     linePath.AddLine(0, this.Height / 2, this.Width, this.Height / 2);
225                     break;
226                 case ConduitStyle.Horizontal_Up_None:
227                     path.AddLines(new PointF[]
228                     { 
229                         new PointF(0, 0), 
230                         new PointF(this.ClientRectangle.Right, 0),
231                         new PointF(this.ClientRectangle.Right, this.Height),
232                         new PointF(0+intPenWidth, this.Height)
233                     });
234                     path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
235                     path.CloseAllFigures();
236 
237                     linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
238                     linePath.AddLine(intPenWidth, this.Height / 2, this.Width, this.Height / 2);
239 
240                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
241                     break;
242                 case ConduitStyle.Horizontal_Down_None:
243                     path.AddLines(new PointF[]
244                     { 
245                         new PointF(intPenWidth, 0), 
246                         new PointF(this.ClientRectangle.Right, 0),
247                         new PointF(this.ClientRectangle.Right, this.Height),
248                         new PointF(0, this.Height)
249                     });
250                     path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
251                     path.CloseAllFigures();
252 
253                     linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
254                     linePath.AddLine(intPenWidth + 1, this.Height / 2, this.Width, this.Height / 2);
255 
256                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
257                     break;
258                 case ConduitStyle.Horizontal_None_Up:
259                     path.AddLines(new PointF[]
260                     { 
261                         new PointF(this.ClientRectangle.Right-intPenWidth, this.Height),
262                         new PointF(0, this.Height),
263                         new PointF(0, 0), 
264                         new PointF(this.ClientRectangle.Right-intPenWidth, 0)
265                     });
266                     path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
267                     path.CloseAllFigures();
268 
269                     linePath.AddLine(0, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
270                     linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
271 
272                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
273                     break;
274                 case ConduitStyle.Horizontal_None_Down:
275                     path.AddLines(new PointF[]
276                     { 
277                         new PointF(this.ClientRectangle.Right, this.Height),
278                         new PointF(0, this.Height),
279                         new PointF(0, 0), 
280                         new PointF(this.ClientRectangle.Right-intPenWidth, 0)
281                     });
282                     path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
283                     path.CloseAllFigures();
284 
285                     linePath.AddLine(0, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
286                     linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
287 
288                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
289                     break;
290                 case ConduitStyle.Horizontal_Down_Up:
291                     path.AddLine(new Point(intPenWidth, 0), new Point(this.Width, 0));
292                     path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
293                     path.AddLine(new Point(this.Width - intPenWidth, this.Height), new Point(0, this.Height));
294                     path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
295                     path.CloseAllFigures();
296 
297                     linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
298                     //linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
299                     linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
300 
301                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
302                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
303                     break;
304                 case ConduitStyle.Horizontal_Up_Down:
305                     path.AddLine(new Point(0, 0), new Point(this.Width - intPenWidth, 0));
306                     path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
307                     path.AddLine(new Point(this.Width, this.Height), new Point(intPenWidth, this.Height));
308                     path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
309                     path.CloseAllFigures();
310 
311                     linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
312                     linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
313                     linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
314 
315                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
316                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
317                     break;
318                 case ConduitStyle.Horizontal_Up_Up:
319                     path.AddLine(new Point(0, 0), new Point(this.Width, 0));
320                     path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
321                     path.AddLine(new Point(this.Width - intPenWidth, this.Height), new Point(intPenWidth, this.Height));
322                     path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
323                     path.CloseAllFigures();
324 
325                     linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
326                     //linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
327                     linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);
328 
329                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
330                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
331                     break;
332                 case ConduitStyle.Horizontal_Down_Down:
333                     path.AddLine(new Point(intPenWidth, 0), new Point(this.Width - intPenWidth, 0));
334                     path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
335                     path.AddLine(new Point(this.Width, this.Height), new Point(0, this.Height));
336                     path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
337                     path.CloseAllFigures();
338 
339                     linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
340                     linePath.AddLine(intPenWidth + 1, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
341                     linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);
342 
343                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
344                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
345                     break;
346                 #endregion
347 
348                 #region V    English:V
349                 case ConduitStyle.Vertical_None_None:
350                     path.AddLines(new PointF[]
351                     { 
352                         new PointF(0, 0), 
353                         new PointF(this.ClientRectangle.Right, 0),
354                         new PointF(this.ClientRectangle.Right, this.Height),
355                         new PointF(0, this.Height)
356                     });
357                     path.CloseAllFigures();
358                     linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height);
359                     break;
360                 case ConduitStyle.Vertical_Left_None:
361                     path.AddLines(new PointF[]
362                     { 
363                         new PointF(this.ClientRectangle.Right, intPenWidth),
364                         new PointF(this.ClientRectangle.Right, this.Height),
365                         new PointF(0, this.Height),
366                         new PointF(0, 0)
367                     });
368                     path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
369                     path.CloseAllFigures();
370 
371                     linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
372                     linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height);
373 
374                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
375                     break;
376                 case ConduitStyle.Vertical_Right_None:
377                     path.AddLines(new PointF[]
378                     { 
379                         new PointF(this.ClientRectangle.Right, 0),
380                         new PointF(this.ClientRectangle.Right, this.Height),
381                         new PointF(0, this.Height),
382                         new PointF(0, intPenWidth)
383                     });
384                     path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
385                     path.CloseAllFigures();
386 
387                     linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
388                     linePath.AddLine(intPenWidth / 2, intPenWidth + 1, intPenWidth / 2, this.Height);
389 
390                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
391                     break;
392                 case ConduitStyle.Vertical_None_Left:
393                     path.AddLines(new PointF[]
394                     { 
395                         new PointF(0, this.Height),
396                         new PointF(0, 0),
397                         new PointF(this.ClientRectangle.Right, 0),
398                         new PointF(this.ClientRectangle.Right, this.Height-intPenWidth),
399                     });
400                     path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
401                     path.CloseAllFigures();
402 
403                     linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height - intPenWidth);
404                     linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
405 
406                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
407                     break;
408                 case ConduitStyle.Vertical_None_Right:
409                     path.AddLines(new PointF[]
410                     { 
411                         new PointF(0, this.Height-intPenWidth),
412                         new PointF(0, 0),
413                         new PointF(this.ClientRectangle.Right, 0),
414                         new PointF(this.ClientRectangle.Right, this.Height),
415                     });
416                     path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
417                     path.CloseAllFigures();
418 
419                     linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height - intPenWidth - 1);
420                     linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
421 
422                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
423                     break;
424                 case ConduitStyle.Vertical_Left_Right:
425                     path.AddLine(this.Width, intPenWidth, this.Width, this.Height);
426                     path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
427                     path.AddLine(0, this.Height - intPenWidth, 0, 0);
428                     path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
429                     path.CloseAllFigures();
430 
431                     linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
432                     //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
433                     linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
434 
435                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
436                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
437                     break;
438                 case ConduitStyle.Vertical_Right_Left:
439                     path.AddLine(this.Width, 0, this.Width, this.Height - intPenWidth);
440                     path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
441                     path.AddLine(0, this.Height, 0, intPenWidth);
442                     path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
443                     path.CloseAllFigures();
444 
445                     linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
446                     //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
447                     linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
448 
449                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
450                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
451                     break;
452                 case ConduitStyle.Vertical_Left_Left:
453                     path.AddLine(this.Width, intPenWidth, this.Width, this.Height - intPenWidth);
454                     path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
455                     path.AddLine(0, this.Height, 0, 0);
456                     path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
457                     path.CloseAllFigures();
458 
459                     linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
460                     //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
461                     linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);
462 
463                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
464                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
465                     break;
466                 case ConduitStyle.Vertical_Right_Right:
467                     path.AddLine(this.Width, 0, this.Width, this.Height);
468                     path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
469                     path.AddLine(0, this.Height - intPenWidth, 0, intPenWidth);
470                     path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
471                     path.CloseAllFigures();
472 
473                     linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
474                     //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
475                     linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 180, -91);
476 
477                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
478                     lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
479                     break;
480                 #endregion
481             }
482             g.FillPath(new SolidBrush(conduitColor), path);
483 
484             //漸變色
485             int intCount = intPenWidth / 2 / 4;
486             int intSplit = (255 - 100) / intCount;
487             for (int i = 0; i < intCount; i++)
488             {
489                 int _penWidth = intPenWidth / 2 - 4 * i;
490                 if (_penWidth <= 0)
491                     _penWidth = 1;
492                 g.DrawPath(new Pen(new SolidBrush(Color.FromArgb(40, Color.White.R, Color.White.G, Color.White.B)), _penWidth), linePath);
493                 if (_penWidth == 1)
494                     break;
495             }
496 
497             g.SetGDIHigh();
498             //使用抗鋸齒畫圓角
499             foreach (var item in lstArcs)
500             {
501                 g.DrawArc(new Pen(new SolidBrush(this.BackColor)), item.rect, item.startAngle, item.sweepAngle);
502             }
503 
504             //液體流動
505             if (LiquidDirection != Conduit.LiquidDirection.None)
506             {
507                 Pen p = new Pen(new SolidBrush(liquidColor), 4);
508                 p.DashPattern = new float[] { 6, 6 };
509                 p.DashOffset = intLineLeft * (LiquidDirection == Conduit.LiquidDirection.Forward ? -1 : 1);
510                 g.DrawPath(p, linePath);
511             }
512         }
513 
514 
515         /// <summary>
516         /// Class ArcEntity.
517         /// </summary>
518         class ArcEntity
519         {
520             /// <summary>
521             /// Gets or sets the rect.
522             /// </summary>
523             /// <value>The rect.</value>
524             public Rectangle rect { get; set; }
525             /// <summary>
526             /// Gets or sets the start angle.
527             /// </summary>
528             /// <value>The start angle.</value>
529             public float startAngle { get; set; }
530             /// <summary>
531             /// Gets or sets the sweep angle.
532             /// </summary>
533             /// <value>The sweep angle.</value>
534             public float sweepAngle { get; set; }
535         }
536 
537     }
538 
539     /// <summary>
540     /// Enum LiquidDirection
541     /// </summary>
542