(五十五)c#Winform自定义控件-管道(工业)

前提

入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章。

官网:https://www.hzhcontrols.cn

GitHub:https://github.com/kwwwvagaa/NetWinformControl

码云:HZHControls控件库: HZHControls控件库,c#的winform自定义控件,对触屏具有更好的操作支持,项目是基于framework4.0,完全原生控件开发,没有使用任何第三方控件,你可以放心的用在你的项目中(winfromcontrol/winformcontrol/.net)。还有更丰富的工业控件持续增加中~~~

如果觉得写的还行,请点个 star 支持一下吧

欢迎前来交流探讨: 企鹅群568015492 企鹅群568015492

麻烦博客下方点个【推荐】,谢谢

NuGet

Install-Package HZH_Controls

目录

c#Winform自定义控件-目录_c#winform自定义控件-有图标的按钮-CSDN博客

用处及效果

准备工作

使用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为抗锯齿模式,把圆角重画一遍,就没有锯齿感了

然后根据中心线,画液体就可以了

完整代码

// ***********************************************************************
// Assembly         : HZH_Controls
// Created          : 2019-09-04
//
// ***********************************************************************
// <copyright file="UCConduit.cs">
//     Copyright by Huang Zhenghui(黄正辉) All, QQ group:568015492 QQ:623128629 Email:623128629@qq.com
// </copyright>
//
// Blog: https://www.cnblogs.com/bfyx
// GitHub:https://github.com/kwwwvagaa/NetWinformControl
// gitee:https://gitee.com/kwwwvagaa/net_winform_custom_control.git
//
// If you use this code, please keep this note.
// ***********************************************************************
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;

namespace HZH_Controls.Controls.Conduit
{
    /// <summary>
    /// Class UCConduit.
    /// Implements the <see cref="System.Windows.Forms.UserControl" />
    /// </summary>
    /// <seealso cref="System.Windows.Forms.UserControl" />
    public class UCConduit : UserControl
    {
        /// <summary>
        /// The conduit style
        /// </summary>
        private ConduitStyle conduitStyle = ConduitStyle.Horizontal_None_None;

        /// <summary>
        /// Gets or sets the conduit style.
        /// </summary>
        /// <value>The conduit style.</value>
        [Description("样式"), Category("自定义")]
        public ConduitStyle ConduitStyle
        {
            get { return conduitStyle; }
            set
            {
                string strOld = conduitStyle.ToString().Substring(0, 1);
                string strNew = value.ToString().Substring(0, 1);
                conduitStyle = value;
                if (strOld != strNew)
                {
                    this.Size = new Size(this.Size.Height, this.Size.Width);
                }
                Refresh();
            }
        }

        /// <summary>
        /// The conduit color
        /// </summary>
        private Color conduitColor = Color.FromArgb(255, 77, 59);
        [Description("颜色"), Category("自定义")]
        /// <summary>
        /// Gets or sets the color of the conduit.
        /// </summary>
        /// <value>The color of the conduit.</value>
        public Color ConduitColor
        {
            get { return conduitColor; }
            set
            {
                conduitColor = value;
                Refresh();
            }
        }

        /// <summary>
        /// The liquid color
        /// </summary>
        private Color liquidColor = Color.FromArgb(3, 169, 243);

        /// <summary>
        /// Gets or sets the color of the liquid.
        /// </summary>
        /// <value>The color of the liquid.</value>
        [Description("液体颜色"), Category("自定义")]
        public Color LiquidColor
        {
            get { return liquidColor; }
            set
            {
                liquidColor = value;
                if (liquidDirection != Conduit.LiquidDirection.None)
                    Refresh();
            }
        }

        /// <summary>
        /// The liquid direction
        /// </summary>
        private LiquidDirection liquidDirection = LiquidDirection.Forward;

        /// <summary>
        /// Gets or sets the liquid direction.
        /// </summary>
        /// <value>The liquid direction.</value>
        [Description("液体流动方向"), Category("自定义")]
        public LiquidDirection LiquidDirection
        {
            get { return liquidDirection; }
            set
            {
                liquidDirection = value;
                Refresh();
            }
        }

        /// <summary>
        /// The liquid speed
        /// </summary>
        private int liquidSpeed = 100;

        /// <summary>
        /// 液体流速,越小,速度越快Gets or sets the liquid speed.
        /// </summary>
        /// <value>The liquid speed.</value>
        [Description("液体流速,越小,速度越快"), Category("自定义")]
        public int LiquidSpeed
        {
            get { return liquidSpeed; }
            set
            {
                if (value <= 0)
                    return;
                liquidSpeed = value;
                m_timer.Interval = value;
            }
        }

        /// <summary>
        /// The int pen width
        /// </summary>
        int intPenWidth = 0;

        /// <summary>
        /// The int line left
        /// </summary>
        int intLineLeft = 0;
        /// <summary>
        /// The m timer
        /// </summary>
        Timer m_timer;
        /// <summary>
        /// Initializes a new instance of the <see cref="UCConduit"/> class.
        /// </summary>
        public UCConduit()
        {
            this.SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            this.SetStyle(ControlStyles.DoubleBuffer, true);
            this.SetStyle(ControlStyles.ResizeRedraw, true);
            this.SetStyle(ControlStyles.Selectable, true);
            this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
            this.SetStyle(ControlStyles.UserPaint, true);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
            this.SizeChanged += UCConduit_SizeChanged;
            this.Size = new Size(200, 50);
            m_timer = new Timer();
            m_timer.Interval = 100;
            m_timer.Tick += timer_Tick;
            m_timer.Enabled = true;
        }

        /// <summary>
        /// Handles the Tick event of the timer control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        void timer_Tick(object sender, EventArgs e)
        {
            intLineLeft += 2;
            if (intLineLeft > 12)
                intLineLeft = 0;
            Refresh();
        }


        /// <summary>
        /// Handles the SizeChanged event of the UCConduit control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs"/> instance containing the event data.</param>
        void UCConduit_SizeChanged(object sender, EventArgs e)
        {
            intPenWidth = conduitStyle.ToString().StartsWith("H") ? this.Height : this.Width;
        }

        /// <summary>
        /// 引发 <see cref="E:System.Windows.Forms.Control.Paint" /> 事件。
        /// </summary>
        /// <param name="e">包含事件数据的 <see cref="T:System.Windows.Forms.PaintEventArgs" />。</param>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;

            List<ArcEntity> lstArcs = new List<ArcEntity>();

            GraphicsPath path = new GraphicsPath();
            GraphicsPath linePath = new GraphicsPath();
            switch (conduitStyle)
            {
                #region H    English:H
                case ConduitStyle.Horizontal_None_None:
                    path.AddLines(new PointF[]
                    { 
                        new PointF(0, 0), 
                        new PointF(this.ClientRectangle.Right, 0),
                        new PointF(this.ClientRectangle.Right, this.Height),
                        new PointF(0, this.Height)
                    });
                    path.CloseAllFigures();
                    linePath.AddLine(0, this.Height / 2, this.Width, this.Height / 2);
                    break;
                case ConduitStyle.Horizontal_Up_None:
                    path.AddLines(new PointF[]
                    { 
                        new PointF(0, 0), 
                        new PointF(this.ClientRectangle.Right, 0),
                        new PointF(this.ClientRectangle.Right, this.Height),
                        new PointF(0+intPenWidth, this.Height)
                    });
                    path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
                    path.CloseAllFigures();

                    linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
                    linePath.AddLine(intPenWidth, this.Height / 2, this.Width, this.Height / 2);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
                    break;
                case ConduitStyle.Horizontal_Down_None:
                    path.AddLines(new PointF[]
                    { 
                        new PointF(intPenWidth, 0), 
                        new PointF(this.ClientRectangle.Right, 0),
                        new PointF(this.ClientRectangle.Right, this.Height),
                        new PointF(0, this.Height)
                    });
                    path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
                    path.CloseAllFigures();

                    linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
                    linePath.AddLine(intPenWidth + 1, this.Height / 2, this.Width, this.Height / 2);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
                    break;
                case ConduitStyle.Horizontal_None_Up:
                    path.AddLines(new PointF[]
                    { 
                        new PointF(this.ClientRectangle.Right-intPenWidth, this.Height),
                        new PointF(0, this.Height),
                        new PointF(0, 0), 
                        new PointF(this.ClientRectangle.Right-intPenWidth, 0)
                    });
                    path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
                    path.CloseAllFigures();

                    linePath.AddLine(0, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
                    linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
                    break;
                case ConduitStyle.Horizontal_None_Down:
                    path.AddLines(new PointF[]
                    { 
                        new PointF(this.ClientRectangle.Right, this.Height),
                        new PointF(0, this.Height),
                        new PointF(0, 0), 
                        new PointF(this.ClientRectangle.Right-intPenWidth, 0)
                    });
                    path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
                    path.CloseAllFigures();

                    linePath.AddLine(0, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
                    linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
                    break;
                case ConduitStyle.Horizontal_Down_Up:
                    path.AddLine(new Point(intPenWidth, 0), new Point(this.Width, 0));
                    path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
                    path.AddLine(new Point(this.Width - intPenWidth, this.Height), new Point(0, this.Height));
                    path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
                    path.CloseAllFigures();

                    linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
                    //linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
                    linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
                    break;
                case ConduitStyle.Horizontal_Up_Down:
                    path.AddLine(new Point(0, 0), new Point(this.Width - intPenWidth, 0));
                    path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
                    path.AddLine(new Point(this.Width, this.Height), new Point(intPenWidth, this.Height));
                    path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
                    path.CloseAllFigures();

                    linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
                    linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
                    linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
                    break;
                case ConduitStyle.Horizontal_Up_Up:
                    path.AddLine(new Point(0, 0), new Point(this.Width, 0));
                    path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 0, 90);
                    path.AddLine(new Point(this.Width - intPenWidth, this.Height), new Point(intPenWidth, this.Height));
                    path.AddArc(new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), 90, 90);
                    path.CloseAllFigures();

                    linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);
                    //linePath.AddLine(intPenWidth, this.Height / 2, this.Width - intPenWidth, this.Height / 2);
                    linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, -1 * intPenWidth / 2 - 1, intPenWidth, intPenWidth), 91, -91);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, intPenWidth * -1, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
                    break;
                case ConduitStyle.Horizontal_Down_Down:
                    path.AddLine(new Point(intPenWidth, 0), new Point(this.Width - intPenWidth, 0));
                    path.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), 270, 90);
                    path.AddLine(new Point(this.Width, this.Height), new Point(0, this.Height));
                    path.AddArc(new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), 180, 90);
                    path.CloseAllFigures();

                    linePath.AddArc(new Rectangle(intPenWidth / 2 + 1, this.Height / 2, intPenWidth, intPenWidth), 179, 91);
                    linePath.AddLine(intPenWidth + 1, this.Height / 2, this.Width - intPenWidth - 1, this.Height / 2);
                    linePath.AddArc(new Rectangle(this.ClientRectangle.Right - intPenWidth - intPenWidth / 2 - 1, intPenWidth / 2, intPenWidth, intPenWidth), 269, 91);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(0, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(this.ClientRectangle.Right - intPenWidth * 2, -1, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
                    break;
                #endregion

                #region V    English:V
                case ConduitStyle.Vertical_None_None:
                    path.AddLines(new PointF[]
                    { 
                        new PointF(0, 0), 
                        new PointF(this.ClientRectangle.Right, 0),
                        new PointF(this.ClientRectangle.Right, this.Height),
                        new PointF(0, this.Height)
                    });
                    path.CloseAllFigures();
                    linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height);
                    break;
                case ConduitStyle.Vertical_Left_None:
                    path.AddLines(new PointF[]
                    { 
                        new PointF(this.ClientRectangle.Right, intPenWidth),
                        new PointF(this.ClientRectangle.Right, this.Height),
                        new PointF(0, this.Height),
                        new PointF(0, 0)
                    });
                    path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
                    path.CloseAllFigures();

                    linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
                    linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
                    break;
                case ConduitStyle.Vertical_Right_None:
                    path.AddLines(new PointF[]
                    { 
                        new PointF(this.ClientRectangle.Right, 0),
                        new PointF(this.ClientRectangle.Right, this.Height),
                        new PointF(0, this.Height),
                        new PointF(0, intPenWidth)
                    });
                    path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
                    path.CloseAllFigures();

                    linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
                    linePath.AddLine(intPenWidth / 2, intPenWidth + 1, intPenWidth / 2, this.Height);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
                    break;
                case ConduitStyle.Vertical_None_Left:
                    path.AddLines(new PointF[]
                    { 
                        new PointF(0, this.Height),
                        new PointF(0, 0),
                        new PointF(this.ClientRectangle.Right, 0),
                        new PointF(this.ClientRectangle.Right, this.Height-intPenWidth),
                    });
                    path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
                    path.CloseAllFigures();

                    linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height - intPenWidth);
                    linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
                    break;
                case ConduitStyle.Vertical_None_Right:
                    path.AddLines(new PointF[]
                    { 
                        new PointF(0, this.Height-intPenWidth),
                        new PointF(0, 0),
                        new PointF(this.ClientRectangle.Right, 0),
                        new PointF(this.ClientRectangle.Right, this.Height),
                    });
                    path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
                    path.CloseAllFigures();

                    linePath.AddLine(this.Width / 2, 0, this.Width / 2, this.Height - intPenWidth - 1);
                    linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
                    break;
                case ConduitStyle.Vertical_Left_Right:
                    path.AddLine(this.Width, intPenWidth, this.Width, this.Height);
                    path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
                    path.AddLine(0, this.Height - intPenWidth, 0, 0);
                    path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
                    path.CloseAllFigures();

                    linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
                    //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
                    linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 181, -91);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
                    break;
                case ConduitStyle.Vertical_Right_Left:
                    path.AddLine(this.Width, 0, this.Width, this.Height - intPenWidth);
                    path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
                    path.AddLine(0, this.Height, 0, intPenWidth);
                    path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
                    path.CloseAllFigures();

                    linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
                    //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
                    linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
                    break;
                case ConduitStyle.Vertical_Left_Left:
                    path.AddLine(this.Width, intPenWidth, this.Width, this.Height - intPenWidth);
                    path.AddArc(new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 0, 90);
                    path.AddLine(0, this.Height, 0, 0);
                    path.AddArc(new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), 270, 90);
                    path.CloseAllFigures();

                    linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 269, 91);
                    //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
                    linePath.AddArc(new Rectangle(-1 * intPenWidth / 2 - 1, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), -1, 91);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 270, sweepAngle = 90 });
                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1 * intPenWidth, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 0, sweepAngle = 90 });
                    break;
                case ConduitStyle.Vertical_Right_Right:
                    path.AddLine(this.Width, 0, this.Width, this.Height);
                    path.AddArc(new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), 90, 90);
                    path.AddLine(0, this.Height - intPenWidth, 0, intPenWidth);
                    path.AddArc(new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), 180, 90);
                    path.CloseAllFigures();

                    linePath.AddArc(new Rectangle(intPenWidth / 2, intPenWidth / 2 + 1, intPenWidth, intPenWidth), 271, -91);
                    //linePath.AddLine(intPenWidth / 2, intPenWidth, intPenWidth / 2, this.Height - intPenWidth);
                    linePath.AddArc(new Rectangle(intPenWidth / 2, this.Height - intPenWidth - intPenWidth / 2 - 1, intPenWidth, intPenWidth), 180, -91);

                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, 0, intPenWidth * 2, intPenWidth * 2), startAngle = 180, sweepAngle = 90 });
                    lstArcs.Add(new ArcEntity() { rect = new Rectangle(-1, this.Height - intPenWidth * 2, intPenWidth * 2, intPenWidth * 2), startAngle = 90, sweepAngle = 90 });
                    break;
                #endregion
            }
            g.FillPath(new SolidBrush(conduitColor), path);

            //渐变色
            int intCount = intPenWidth / 2 / 4;
            int intSplit = (255 - 100) / intCount;
            for (int i = 0; i < intCount; i++)
            {
                int _penWidth = intPenWidth / 2 - 4 * i;
                if (_penWidth <= 0)
                    _penWidth = 1;
                g.DrawPath(new Pen(new SolidBrush(Color.FromArgb(40, Color.White.R, Color.White.G, Color.White.B)), _penWidth), linePath);
                if (_penWidth == 1)
                    break;
            }

            g.SetGDIHigh();
            //使用抗锯齿画圆角
            foreach (var item in lstArcs)
            {
                g.DrawArc(new Pen(new SolidBrush(this.BackColor)), item.rect, item.startAngle, item.sweepAngle);
            }

            //液体流动
            if (LiquidDirection != Conduit.LiquidDirection.None)
            {
                Pen p = new Pen(new SolidBrush(liquidColor), 4);
                p.DashPattern = new float[] { 6, 6 };
                p.DashOffset = intLineLeft * (LiquidDirection == Conduit.LiquidDirection.Forward ? -1 : 1);
                g.DrawPath(p, linePath);
            }
        }


        /// <summary>
        /// Class ArcEntity.
        /// </summary>
        class ArcEntity
        {
            /// <summary>
            /// Gets or sets the rect.
            /// </summary>
            /// <value>The rect.</value>
            public Rectangle rect { get; set; }
            /// <summary>
            /// Gets or sets the start angle.
            /// </summary>
            /// <value>The start angle.</value>
            public float startAngle { get; set; }
            /// <summary>
            /// Gets or sets the sweep angle.
            /// </summary>
            /// <value>The sweep angle.</value>
            public float sweepAngle { get; set; }
        }

    }

    /// <summary>
    /// Enum LiquidDirection
    /// </summary>
    public enum LiquidDirection
    {
        /// <summary>
        /// The none
        /// </summary>
        None,
        /// <summary>
        /// The forward
        /// </summary>
        Forward,
        /// <summary>
        /// The backward
        /// </summary>
        Backward
    }

    /// <summary>
    /// 管道样式Enum ConduitStyle
    /// </summary>
    public enum ConduitStyle
    {
        /// <summary>
        /// 直线 The horizontal none none
        /// </summary>
        Horizontal_None_None,
        /// <summary>
        /// 左上The horizontal up none
        /// </summary>
        Horizontal_Up_None,
        /// <summary>
        /// 左下The horizontal down none
        /// </summary>
        Horizontal_Down_None,
        /// <summary>
        /// 右上The horizontal none up
        /// </summary>
        Horizontal_None_Up,
        /// <summary>
        /// 右下The horizontal none down
        /// </summary>
        Horizontal_None_Down,
        /// <summary>
        /// 左下右上The horizontal down up
        /// </summary>
        Horizontal_Down_Up,
        /// <summary>
        /// 左上右下The horizontal up down
        /// </summary>
        Horizontal_Up_Down,
        /// <summary>
        /// 左上,右上The horizontal up up
        /// </summary>
        Horizontal_Up_Up,
        /// <summary>
        /// 左下右下The horizontal down down
        /// </summary>
        Horizontal_Down_Down,

        /// <summary>
        /// 竖线The vertical none none
        /// </summary>
        Vertical_None_None,
        /// <summary>
        /// 上左The vertical left none
        /// </summary>
        Vertical_Left_None,
        /// <summary>
        /// 上右The vertical right none
        /// </summary>
        Vertical_Right_None,
        /// <summary>
        /// 下左The vertical none left
        /// </summary>
        Vertical_None_Left,
        /// <summary>
        /// 下右The vertical none right
        /// </summary>
        Vertical_None_Right,
        /// <summary>
        /// 上左下右The vertical left right
        /// </summary>
        Vertical_Left_Right,
        /// <summary>
        /// 上右下左The vertical right left
        /// </summary>
        Vertical_Right_Left,
        /// <summary>
        /// 上左下左The vertical left left
        /// </summary>
        Vertical_Left_Left,
        /// <summary>
        /// 上右下右The vertical right left
        /// </summary>
        Vertical_Right_Right,
    }
}

最后的话

如果你喜欢的话,请到 HZHControls控件库: HZHControls控件库,c#的winform自定义控件,对触屏具有更好的操作支持,项目是基于framework4.0,完全原生控件开发,没有使用任何第三方控件,你可以放心的用在你的项目中(winfromcontrol/winformcontrol/.net)。还有更丰富的工业控件持续增加中~~~ 点个星星吧

WinForms中的自定义控件开发允许开发者创建具有特定功能的控件,这些控件可以用于多种应用程序。仪表盘控件是一种常见的自定义控件,它模拟物理仪表盘,用于显示从简单到复杂的各种数据。在C#中开发WinForms仪表盘控件通常涉及以下几个步骤: 1. **创建控件类**:首先,你需要继承自`UserControl`类,创建一个新的类,这个类将作为基础来定义你的仪表盘控件。 2. **设计界面**:在类中,使用设计器或代码来绘制控件的用户界面。这可能包括刻度、指针和数据标签等元素。 3. **编写业务逻辑**:实现控件的数据绑定和逻辑处理,这可能包括如何读取和显示数据,以及如何响应用户的交互。 4. **属性和事件**:定义公共属性来获取和设置控件的外观和行为,如颜色、范围等,并且创建事件以允许外部代码响应特定的用户操作,如值改变等。 5. **测试和调试**:在完成开发后,需要对控件进行彻底的测试,确保在不同情况下都能正确工作。 以下是一个简单的示例代码,展示了如何创建一个基础的仪表盘控件: ```csharp using System; using System.Drawing; using System.Windows.Forms; public class DashboardControl : UserControl { private float value = 0; // 仪表盘的当前值 // 公共属性,允许外部设置仪表盘值 public float Value { get { return value; } set { if (value != this.value) { this.value = value; Invalidate(); // 重绘控件 } } } // 绘制控件 protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); Graphics g = e.Graphics; // 绘制仪表盘的刻度和指针等 // ... } // 其他方法,如响应用户事件等 } ``` 开发自定义控件是一个复杂的过程,它需要深入了解WinForms框架、GDI+绘图以及可能涉及的动画和数据绑定技术。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值