前提
入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。
GitHub:https://github.com/kwwwvagaa/NetWinformControl
码云:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
如果觉得写的还行,请点个 star 支持一下吧
麻烦博客下方点个【推荐】,谢谢
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:623128629@qq.com 8 // </copyright> 9 // 10 // Blog: https://www.cnblogs.com/bfyx 11 // GitHub:https://github.com/kwwwvagaa/NetWinformControl 12 // gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git 13 // 14 // If you use this code, please keep this note. 15 // *********************************************************************** 16 using System; 17 using System.Collections.Generic; 18 using System.Linq; 19 using System.Text; 20 using System.Windows.Forms; 21 using System.Drawing; 22 using System.Drawing.Drawing2D; 23 using 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 public enum LiquidDirection 543 { 544 /// <summary> 545 /// The none 546 /// </summary> 547 None, 548 /// <summary> 549 /// The forward 550 /// </summary> 551 Forward, 552 /// <summary> 553 /// The backward 554 /// </summary> 555 Backward 556 } 557 558 /// <summary> 559 /// 管道样式Enum ConduitStyle 560 /// </summary> 561 public enum ConduitStyle 562 { 563 /// <summary> 564 /// 直线 The horizontal none none 565 /// </summary> 566 Horizontal_None_None, 567 /// <summary> 568 /// 左上The horizontal up none 569 /// </summary> 570 Horizontal_Up_None, 571 /// <summary> 572 /// 左下The horizontal down none 573 /// </summary> 574 Horizontal_Down_None, 575 /// <summary> 576 /// 右上The horizontal none up 577 /// </summary> 578 Horizontal_None_Up, 579 /// <summary> 580 /// 右下The horizontal none down 581 /// </summary> 582 Horizontal_None_Down, 583 /// <summary> 584 /// 左下右上The horizontal down up 585 /// </summary> 586 Horizontal_Down_Up, 587 /// <summary> 588 /// 左上右下The horizontal up down 589 /// </summary> 590 Horizontal_Up_Down, 591 /// <summary> 592 /// 左上,右上The horizontal up up 593 /// </summary> 594 Horizontal_Up_Up, 595 /// <summary> 596 /// 左下右下The horizontal down down 597 /// </summary> 598 Horizontal_Down_Down, 599 600 /// <summary> 601 /// 竖线The vertical none none 602 /// </summary> 603 Vertical_None_None, 604 /// <summary> 605 /// 上左The vertical left none 606 /// </summary> 607 Vertical_Left_None, 608 /// <summary> 609 /// 上右The vertical right none 610 /// </summary> 611 Vertical_Right_None, 612 /// <summary> 613 /// 下左The vertical none left 614 /// </summary> 615 Vertical_None_Left, 616 /// <summary> 617 /// 下右The vertical none right 618 /// </summary> 619 Vertical_None_Right, 620 /// <summary> 621 /// 上左下右The vertical left right 622 /// </summary> 623 Vertical_Left_Right, 624 /// <summary> 625 /// 上右下左The vertical right left 626 /// </summary> 627 Vertical_Right_Left, 628 /// <summary> 629 /// 上左下左The vertical left left 630 /// </summary> 631 Vertical_Left_Left, 632 /// <summary> 633 /// 上右下右The vertical right left 634 /// </summary> 635 Vertical_Right_Right, 636 } 637 }
最后的话
如果你喜欢的话,请到 https://gitee.com/kwwwvagaa/net_winform_custom_control 点个星星吧