前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_contr ...
前提
入行已經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.Rig