using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing.Drawing2D; using System.Drawing.Text; using System.Drawing; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace Mesnac.Controls.ChemicalWeighing { /// 一个简单的管道线控件,只能横竖两种模式,支持流动动画显示 [Description("管道流动控件,支持横竖模式,支持显示流动动画,多个控件组合使用出更高级的效果")] public class HslPipeLineThree : UserControl { private ArrowDirection arrowDirection = ArrowDirection.Down; private Color centerColor = Color.LightGray; private Color edgeColor = Color.DimGray; private Pen edgePen = new Pen(Color.DimGray, 1f); private bool isPipeLineActive1 = false; private bool isPipeLineActive2 = false; private bool isPipeLineActive3 = false; private int pipeLineWidth = 3; private Color colorPipeLineCenter = Color.DodgerBlue; private float moveSpeed1 = 0.0f; private float moveSpeed2 = 0.0f; private float moveSpeed3 = 0.0f; private float startOffect1 = 0.0f; private float startOffect2 = 0.0f; private float startOffect3 = 0.0f; private Timer timer = (Timer)null; private int pipeWidth = 30; private float antLength = 5f; /// 必需的设计器变量。 private IContainer components = (IContainer)null; /// 实例化一个默认的管道线对象 public HslPipeLineThree() { this.InitializeComponent(); this.SetStyle(ControlStyles.UserPaint | ControlStyles.SupportsTransparentBackColor, true); this.SetStyle(ControlStyles.OptimizedDoubleBuffer, true); this.SetStyle(ControlStyles.AllPaintingInWmPaint, true); this.timer = new Timer(); this.timer.Interval = 50; this.timer.Tick += new EventHandler(this.Timer_Tick); this.timer.Start(); } /// protected override void OnPaint(PaintEventArgs e) { e.Graphics.SmoothingMode = SmoothingMode.HighQuality; e.Graphics.TextRenderingHint = TextRenderingHint.ClearTypeGridFit; this.PaintHslControls(e.Graphics, this.Width, this.Height); base.OnPaint(e); } /// public void PaintHslControls(Graphics g, int width, int height) { if (this.arrowDirection == ArrowDirection.Down) this.PaintMain(g, width, height); else if (this.arrowDirection == ArrowDirection.Right) { g.TranslateTransform(0.0f, (float)height); g.RotateTransform(-90f); this.PaintMain(g, height, width); g.RotateTransform(90f); g.TranslateTransform(0.0f, (float)-height); } else if (this.arrowDirection == ArrowDirection.Left) { g.TranslateTransform((float)width, 0.0f); g.RotateTransform(90f); this.PaintMain(g, height, width); g.RotateTransform(-90f); g.TranslateTransform((float)-width, 0.0f); } else { g.RotateTransform(-180f); g.TranslateTransform((float)-width, (float)-height); this.PaintMain(g, width, height); g.TranslateTransform((float)width, (float)height); g.RotateTransform(180f); } } private void PaintMain(Graphics g, int width, int height) { ColorBlend colorBlend = new ColorBlend(); colorBlend.Positions = new float[3] { 0.0f, 0.5f, 1f }; colorBlend.Colors = new Color[3] { this.edgeColor, this.centerColor, this.edgeColor }; LinearGradientBrush linearGradientBrush1 = new LinearGradientBrush(new Point(0, 0), new Point(0, this.pipeWidth - 1), this.edgeColor, this.centerColor); linearGradientBrush1.InterpolationColors = colorBlend; g.FillRectangle((Brush)linearGradientBrush1, new Rectangle(0, 0, width, this.pipeWidth - 1)); g.DrawLine(this.edgePen, 0, 0, width, 0); g.DrawLine(this.edgePen, 0, this.pipeWidth - 1, width, this.pipeWidth - 1); linearGradientBrush1.Dispose(); LinearGradientBrush linearGradientBrush2 = new LinearGradientBrush(new Point((width - this.pipeWidth) / 2, 0), new Point((width + this.pipeWidth) / 2, 0), this.edgeColor, this.centerColor); linearGradientBrush2.InterpolationColors = colorBlend; g.FillPolygon((Brush)linearGradientBrush2, new PointF[5] { new PointF((float) (width / 2), (float) (this.pipeWidth / 2)), new PointF((float) ((width - this.pipeWidth) / 2), (float) this.pipeWidth), new PointF((float) ((width - this.pipeWidth) / 2), (float) height), new PointF((float) ((width + this.pipeWidth) / 2 - 1), (float) height), new PointF((float) ((width + this.pipeWidth) / 2 - 1), (float) this.pipeWidth) }); linearGradientBrush2.Dispose(); g.DrawLine(this.edgePen, (width - this.pipeWidth) / 2, this.pipeWidth, (width - this.pipeWidth) / 2, height); g.DrawLine(this.edgePen, (width + this.pipeWidth) / 2 - 1, height, (width + this.pipeWidth) / 2 - 1, this.pipeWidth); GraphicsPath path1 = new GraphicsPath(FillMode.Alternate); GraphicsPath path2 = new GraphicsPath(FillMode.Alternate); GraphicsPath path3 = new GraphicsPath(FillMode.Alternate); if (this.isPipeLineActive1) path1.AddLine(0, this.pipeWidth / 2, width, this.pipeWidth / 2); if (this.isPipeLineActive2) { path2.AddLine(0, this.pipeWidth / 2, (width - this.pipeWidth) / 2, this.pipeWidth / 2); path2.AddArc(new Rectangle(width / 2 - this.pipeWidth, this.pipeWidth / 2, this.pipeWidth, this.pipeWidth), 270f, 90f); path2.AddLine(width / 2, this.pipeWidth, width / 2, height); } if (this.isPipeLineActive3) { path3.AddLine(width / 2, height, width / 2, this.pipeWidth); path3.AddArc(new Rectangle(width / 2, this.pipeWidth / 2, this.pipeWidth, this.pipeWidth), 180f, 90f); path3.AddLine((width + this.pipeWidth) / 2, this.pipeWidth / 2, width, this.pipeWidth / 2); } using (Pen pen = new Pen(this.colorPipeLineCenter, (float)this.pipeLineWidth)) { pen.DashStyle = DashStyle.Custom; pen.DashPattern = new float[2] { this.antLength, 5f }; pen.DashOffset = this.startOffect1; g.DrawPath(pen, path1); pen.DashOffset = this.startOffect2; g.DrawPath(pen, path2); pen.DashOffset = this.startOffect3; g.DrawPath(pen, path3); } path1.Dispose(); path2.Dispose(); path3.Dispose(); } private void PaintRectangleBorder( Graphics g, Brush brush, Pen pen, Rectangle rectangle, bool left, bool right, bool up, bool down) { g.FillRectangle(brush, rectangle); if (left) g.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X, rectangle.Y + rectangle.Height - 1); if (up) g.DrawLine(pen, rectangle.X, rectangle.Y, rectangle.X + rectangle.Width - 1, rectangle.Y); if (right) g.DrawLine(pen, rectangle.X + rectangle.Width - 1, rectangle.Y, rectangle.X + rectangle.Width - 1, rectangle.Y + rectangle.Height - 1); if (!down) return; g.DrawLine(pen, rectangle.X, rectangle.Y + rectangle.Height - 1, rectangle.X + rectangle.Width - 1, rectangle.Y + rectangle.Height - 1); } private void PaintRectangleBorderUpDown(Graphics g, Brush brush, Pen pen, Rectangle rectangle) => this.PaintRectangleBorder(g, brush, pen, rectangle, false, false, true, true); private void Timer_Tick(object sender, EventArgs e) { if (!this.isPipeLineActive1 && !this.isPipeLineActive2 && !this.isPipeLineActive3 || (double)this.moveSpeed1 == 0.0 && (double)this.moveSpeed2 == 0.0 && (double)this.moveSpeed3 == 0.0) return; this.startOffect1 -= this.moveSpeed1; if ((double)this.startOffect1 <= -((double)this.antLength * 2.0) || (double)this.startOffect1 >= (double)this.antLength * 2.0) this.startOffect1 = 0.0f; this.startOffect2 -= this.moveSpeed2; if ((double)this.startOffect2 <= -((double)this.antLength * 2.0) || (double)this.startOffect2 >= (double)this.antLength * 2.0) this.startOffect2 = 0.0f; this.startOffect3 -= this.moveSpeed3; if ((double)this.startOffect3 <= -((double)this.antLength * 2.0) || (double)this.startOffect3 >= (double)this.antLength * 2.0) this.startOffect3 = 0.0f; this.Invalidate(); } /// 获取或设置控件的背景色 [Browsable(true)] [Description("获取或设置控件的背景色")] [Category("HslControls")] [DefaultValue(typeof(Color), "Transparent")] [EditorBrowsable(EditorBrowsableState.Always)] public override Color BackColor { get => base.BackColor; set => base.BackColor = value; } /// 获取或设置管道控件的边缘颜色 [Browsable(true)] [Description("获取或设置管道控件的边缘颜色")] [Category("HslControls")] [DefaultValue(typeof(Color), "DimGray")] public Color EdgeColor { get => this.edgeColor; set { this.edgeColor = value; this.edgePen.Dispose(); this.edgePen = new Pen(value, 1f); this.Invalidate(); } } /// 获取或设置管道控件的中心颜色 [Browsable(true)] [Description("获取或设置管道控件的中心颜色")] [Category("HslControls")] [DefaultValue(typeof(Color), "LightGray")] public Color LineCenterColor { get => this.centerColor; set { this.centerColor = value; this.Invalidate(); } } /// 获取或设置管道控件是否是横向的还是纵向的 [Browsable(true)] [Description("获取或设置管道控件是否是横向的还是纵向的")] [Category("HslControls")] [DefaultValue(typeof(ArrowDirection), "Down")] public ArrowDirection PipeLineStyle { get => this.arrowDirection; set { this.arrowDirection = value; this.Invalidate(); } } /// 获取或设置管道1号线是否激活液体显示 [Browsable(true)] [Description("获取或设置管道线是否激活液体显示")] [Category("HslControls")] [DefaultValue(false)] public bool PipeLineActive1 { get => this.isPipeLineActive1; set { this.isPipeLineActive1 = value; this.Invalidate(); } } /// 获取或设置管道2号线是否激活液体显示 [Browsable(true)] [Description("获取或设置管道线是否激活液体显示")] [Category("HslControls")] [DefaultValue(false)] public bool PipeLineActive2 { get => this.isPipeLineActive2; set { this.isPipeLineActive2 = value; this.Invalidate(); } } /// 获取或设置管道3号线是否激活液体显示 [Browsable(true)] [Description("获取或设置管道线是否激活液体显示")] [Category("HslControls")] [DefaultValue(false)] public bool PipeLineActive3 { get => this.isPipeLineActive3; set { this.isPipeLineActive3 = value; this.Invalidate(); } } /// 获取或设置管道1号线液体流动的速度,0为静止,正数为正向流动,负数为反向流动 [Browsable(true)] [Description("获取或设置管道线液体流动的速度,0为静止,正数为正向流动,负数为反向流动")] [Category("HslControls")] [DefaultValue(0.0f)] public float MoveSpeed1 { get => this.moveSpeed1; set { this.moveSpeed1 = value; this.startOffect1 = 0.0f; this.startOffect2 = 0.0f; this.startOffect3 = 0.0f; this.Invalidate(); } } /// 获取或设置管道2号线液体流动的速度,0为静止,正数为正向流动,负数为反向流动 [Browsable(true)] [Description("获取或设置管道线液体流动的速度,0为静止,正数为正向流动,负数为反向流动")] [Category("HslControls")] [DefaultValue(0.0f)] public float MoveSpeed2 { get => this.moveSpeed2; set { this.moveSpeed2 = value; this.startOffect1 = 0.0f; this.startOffect2 = 0.0f; this.startOffect3 = 0.0f; this.Invalidate(); } } /// 获取或设置管道3号线液体流动的速度,0为静止,正数为正向流动,负数为反向流动 [Browsable(true)] [Description("获取或设置管道线液体流动的速度,0为静止,正数为正向流动,负数为反向流动")] [Category("HslControls")] [DefaultValue(0.0f)] public float MoveSpeed3 { get => this.moveSpeed3; set { this.moveSpeed3 = value; this.startOffect1 = 0.0f; this.startOffect2 = 0.0f; this.startOffect3 = 0.0f; this.Invalidate(); } } /// 获取或设置液体控制的定时器刷新的间隔,默认是50 [Browsable(true)] [Description("获取或设置液体控制的定时器刷新的间隔,默认是50")] [Category("HslControls")] [DefaultValue(50)] public int TimerInterval { get => this.timer.Interval; set => this.timer.Interval = value; } /// 获取或设置中间管道线的宽度信息,默认为3 [Browsable(true)] [Description("获取或设置中间管道线的宽度信息,默认为3")] [Category("HslControls")] [DefaultValue(3)] public int PipeLineWidth { get => this.pipeLineWidth; set { this.pipeLineWidth = value; this.Invalidate(); } } /// 获取或设置流动状态时管道控件的中心颜色 [Browsable(true)] [Description("获取或设置流动状态时管道控件的中心颜色")] [Category("HslControls")] [DefaultValue(typeof(Color), "DodgerBlue")] public Color ActiveLineCenterColor { get => this.colorPipeLineCenter; set { this.colorPipeLineCenter = value; this.Invalidate(); } } /// 获取或设置管道的宽度,默认为30 [Browsable(true)] [Description("获取或设置管道的宽度,默认为30")] [Category("HslControls")] [DefaultValue(30)] public int PipeWidth { get => this.pipeWidth; set { this.pipeWidth = value; this.Invalidate(); } } /// 获取或设置蚂蚁线的长度信息 [Browsable(true)] [Description("获取或设置蚂蚁线的长度信息")] [Category("HslControls")] [DefaultValue(5f)] public float AntLength { get => this.antLength; set { this.antLength = value; this.Invalidate(); } } /// 清理所有正在使用的资源。 /// 如果应释放托管资源,为 true;否则为 false。 protected override void Dispose(bool disposing) { if (disposing && this.components != null) this.components.Dispose(); base.Dispose(disposing); } /// /// 设计器支持所需的方法 - 不要修改 /// 使用代码编辑器修改此方法的内容。 /// private void InitializeComponent() { this.SuspendLayout(); this.AutoScaleMode = AutoScaleMode.None; this.BackColor = Color.Transparent; this.Name = nameof(HslPipeLineThree); this.Size = new Size(135, 83); this.ResumeLayout(false); } } }