using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using System.Windows.Threading; namespace WYL_WPF_Controls { /// <summary> /// UCLineflow.xaml 的交互逻辑 /// </summary> public partial class UCLineflow : UserControl { #region 变量/属性 Path linePath = new Path(); /// <summary> /// 定时器 /// </summary> //private DispatcherTimer m_timer; private System.Timers.Timer m_timer; /// <summary> /// The int pen width /// </summary> int intPenWidth = 0; /// <summary> /// The int line left /// </summary> int intLineLeft = 0; [Description("宽度"), Category("自定义")] public double UcWidth { get { return (double)GetValue(ucwidth); } set { SetValue(ucwidth, value); } } public static readonly DependencyProperty ucwidth = DependencyProperty.Register("UcWidth", typeof(double), typeof(UCLineflow), new FrameworkPropertyMetadata(200.0, FrameworkPropertyMetadataOptions.AffectsRender)); [Description("高度"), Category("自定义")] public double UcHeight { get { return (double)GetValue(ucHeight); } set { SetValue(ucHeight, value); } } public static readonly DependencyProperty ucHeight = DependencyProperty.Register("UcHeight", typeof(double), typeof(UCLineflow), new FrameworkPropertyMetadata(50.0, FrameworkPropertyMetadataOptions.AffectsRender)); [Description("样式"), Category("自定义")] public LineflowStyle Lineflowstyle { get { return (LineflowStyle)GetValue(lineflowstyle); } set { SetValue(lineflowstyle, value); } } public static readonly DependencyProperty lineflowstyle = //DependencyProperty.Register("Lineflowstyle", typeof(LineflowStyle), typeof(UCLineflow), new PropertyMetadata(LineflowStyle.Horizontal_None_None)); DependencyProperty.Register("Lineflowstyle", typeof(LineflowStyle), typeof(UCLineflow), new FrameworkPropertyMetadata(LineflowStyle.Horizontal_None_None, FrameworkPropertyMetadataOptions.AffectsRender)); [Description("颜色"), Category("自定义")] public Brush LineStroke { get { return (Brush)GetValue(lineStroke); } set { SetValue(lineStroke, value); } } public static readonly DependencyProperty lineStroke = //DependencyProperty.Register("LineStroke", typeof(Brush), typeof(UCLineflow), new PropertyMetadata(Brushes.Red)); DependencyProperty.Register("LineStroke", typeof(Brush), typeof(UCLineflow), new FrameworkPropertyMetadata(Brushes.Red, FrameworkPropertyMetadataOptions.AffectsRender)); [Description("液体流动方向"), Category("自定义")] public LiquidDirection Liquid { get { return (LiquidDirection)GetValue(liquidDirection); } set { SetValue(liquidDirection, value); } } public static readonly DependencyProperty liquidDirection = //DependencyProperty.Register("Liquid", typeof(LiquidDirection), typeof(UCLineflow), new PropertyMetadata(LiquidDirection.Forward)); DependencyProperty.Register("Liquid", typeof(LiquidDirection), typeof(UCLineflow), new FrameworkPropertyMetadata(LiquidDirection.Forward, FrameworkPropertyMetadataOptions.AffectsRender)); [Description("液体流速,越小,速度越快"), Category("自定义")] public int LiquidSpeed { get { return (int)GetValue(liquidSpeed); } set { if (value <= 0) return; SetValue(liquidSpeed, value); //m_timer.Interval = TimeSpan.FromMilliseconds(value); m_timer.Interval = value; } } public static readonly DependencyProperty liquidSpeed = DependencyProperty.Register("LiquidSpeed", typeof(int), typeof(UCLineflow), new FrameworkPropertyMetadata(100, FrameworkPropertyMetadataOptions.AffectsRender)); int conduitWidth = 50; [Description("管道宽度,当ConduitStyle的值是Horizontal_Tilt_Up,Horizontal_Tilt_Down,Vertical_Tilt_Left,Vertical_Tilt_Right时有效,其他时候将根据管道大小使用自动宽度"), Category("自定义")] public int ConduitWidth { get { return conduitWidth; } set { conduitWidth = value; } } #endregion public UCLineflow() { InitializeComponent(); this.Loaded += UCLineflow_Loaded; this.Unloaded += UCLineflow_Unloaded; this.SizeChanged += UCLineflow_SizeChanged; //this.Width = 200; //this.Height = 50; //this.RenderSize = new Size(200, 50); //DrawShap(); grid.Children.Add(linePath); //m_timer = new DispatcherTimer(); //m_timer.Interval = TimeSpan.FromMilliseconds(100); m_timer = new System.Timers.Timer(); m_timer.Interval = 100; } private void UCLineflow_SizeChanged(object sender, SizeChangedEventArgs e) { intPenWidth = (int)(Lineflowstyle.ToString().StartsWith("H") ? this.Height : this.Width); //DrawShap(); } private void UCLineflow_Loaded(object sender, RoutedEventArgs e) { //m_timer.Tick += M_timer_Tick; m_timer.Elapsed += M_timer_Elapsed; m_timer.Start(); var dataModel = new LineflowModel { UcWidth = UcWidth, UcHeight = UcHeight }; this.DataContext = dataModel; } private void UCLineflow_Unloaded(object sender, RoutedEventArgs e) { //m_timer.Tick -= M_timer_Tick; m_timer.Elapsed -= M_timer_Elapsed; m_timer.Stop(); m_timer = null; } private void M_timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { intLineLeft += 2; if (intLineLeft >= 12) intLineLeft = 0; this.Dispatcher.BeginInvoke((Action)delegate { linePath.StrokeDashOffset = intLineLeft * (Liquid == LiquidDirection.Forward ? -1 : 1); }); } private void M_timer_Tick(object sender, EventArgs e) { intLineLeft += 2; if (intLineLeft >= 12) intLineLeft = 0; linePath.StrokeDashOffset = intLineLeft * (Liquid == LiquidDirection.Forward ? -1 : 1); //DrawShap(); } /// <summary> /// 重绘 /// </summary> /// <param name="drawingContext"></param> protected override void OnRender(DrawingContext drawingContext) { base.OnRender(drawingContext); if (Liquid == LiquidDirection.None) { m_timer.Stop(); } else { m_timer.Start(); } DrawShap(); } private void DrawShap() { double acH = this.Height; double acW = this.Width; linePath.Stroke = LineStroke; linePath.StrokeThickness = 4; linePath.StrokeDashArray = new DoubleCollection() { 6, 6 }; PathGeometry pathGeometry = new PathGeometry(); PathFigure figure = new PathFigure(); PathSegmentCollection ps = new PathSegmentCollection(); ArcSegment arc = new ArcSegment(); //RotateTransform rt = new RotateTransform(); switch (Lineflowstyle) { #region H English:H case LineflowStyle.Horizontal_None_None: figure.StartPoint = new Point(0, acH/2); ps.Add(new LineSegment(new Point(acW, acH / 2), true)); break; case LineflowStyle.Horizontal_Up_None: figure.StartPoint = new Point(acH / 2, 0); arc.Point = new Point(acH, acH / 2); arc.Size = new Size(acH / 2, acH / 2); ps.Add(arc); ps.Add(new LineSegment(new Point(acW, acH / 2), true)); break; case LineflowStyle.Horizontal_Down_None: figure.StartPoint = new Point(acH / 2, acH); arc.Point = new Point(acH, acH / 2); arc.Size = new Size(acH / 2, acH / 2); arc.SweepDirection = SweepDirection.Clockwise;// ps.Add(arc); ps.Add(new LineSegment(new Point(acW, acH / 2), true)); break; case LineflowStyle.Horizontal_None_Up: figure.StartPoint = new Point(0, acH / 2); ps.Add(new LineSegment(new Point(acW - acH, acH / 2), true)); arc.Point = new Point(acW - acH / 2, 0); arc.Size = new Size(acH / 2, acH / 2); ps.Add(arc); break; case LineflowStyle.Horizontal_None_Down: figure.StartPoint = new Point(0, acH / 2); ps.Add(new LineSegment(new Point(acW - acH, acH / 2), true)); arc.Point = new Point(acW - acH / 2, acH); arc.Size = new Size(acH / 2, acH / 2); arc.SweepDirection = SweepDirection.Clockwise;// ps.Add(arc); break; case LineflowStyle.Horizontal_Down_Up: figure.StartPoint = new Point(acH / 2, acH); arc.Point = new Point(acH, acH / 2); arc.Size = new Size(acH / 2, acH / 2); arc.SweepDirection = SweepDirection.Clockwise;// ps.Add(arc); ps.Add(new LineSegment(new Point(acW - acH, acH / 2), true)); //右边弧度 arc = new ArcSegment(); arc.Point = new Point(acW - acH / 2, 0); arc.Size = new Size(acH / 2, acH / 2); ps.Add(arc); break; case LineflowStyle.Horizontal_Up_Down: figure.StartPoint = new Point(acH / 2, 0); arc.Point = new Point(acH, acH / 2); arc.Size = new Size(acH / 2, acH / 2); ps.Add(arc); ps.Add(new LineSegment(new Point(acW - acH, acH / 2), true)); //右边弧度 arc = new ArcSegment(); arc.Point = new Point(acW - acH / 2, acH); arc.Size = new Size(acH / 2, acH / 2); arc.SweepDirection = SweepDirection.Clockwise;// ps.Add(arc); break; case LineflowStyle.Horizontal_Up_Up: figure.StartPoint = new Point(acH / 2, 0); arc.Point = new Point(acH, acH / 2); arc.Size = new Size(acH / 2, acH / 2); ps.Add(arc); ps.Add(new LineSegment(new Point(acW - acH, acH / 2), true)); //右边弧度 arc = new ArcSegment(); arc.Point = new Point(acW - acH / 2, 0); arc.Size = new Size(acH / 2, acH / 2); ps.Add(arc); break; case LineflowStyle.Horizontal_Down_Down: figure.StartPoint = new Point(acH / 2, acH); arc.Point = new Point(acH, acH / 2); arc.Size = new Size(acH / 2, acH / 2); arc.SweepDirection = SweepDirection.Clockwise;// ps.Add(arc); ps.Add(new LineSegment(new Point(acW - acH, acH / 2), true)); //右边弧度 arc = new ArcSegment(); arc.Point = new Point(acW - acH / 2, acH); arc.Size = new Size(acH / 2, acH / 2); arc.SweepDirection = SweepDirection.Clockwise;// ps.Add(arc); break; case LineflowStyle.Horizontal_Tilt_Up: break; case LineflowStyle.Horizontal_Tilt_Down: break; #region V English:V case LineflowStyle.Vertical_None_None: figure.StartPoint = new Point(acW / 2, 0); ps.Add(new LineSegment(new Point(acW / 2, acH), true)); break; case LineflowStyle.Vertical_Left_None: figure.StartPoint = new Point(0, acW / 2); arc.Point = new Point(acW / 2, acW); arc.Size = new Size(acW / 2, acW / 2); arc.SweepDirection = SweepDirection.Clockwise;// ps.Add(arc); ps.Add(new LineSegment(new Point(acW / 2, acH), true)); break; case LineflowStyle.Vertical_Right_None: figure.StartPoint = new Point(acW, acW / 2); arc.Point = new Point(acW / 2, acW); arc.Size = new Size(acW / 2, acW / 2); ps.Add(arc); ps.Add(new LineSegment(new Point(acW / 2, acH), true)); break; case LineflowStyle.Vertical_None_Left: figure.StartPoint = new Point(acW / 2, 0); ps.Add(new LineSegment(new Point(acW / 2, acH - acW), true)); arc.Point = new Point(0, acH - acW/2); arc.Size = new Size(acW / 2, acW / 2); arc.SweepDirection = SweepDirection.Clockwise;// ps.Add(arc); break; case LineflowStyle.Vertical_None_Right: figure.StartPoint = new Point(acW / 2, 0); ps.Add(new LineSegment(new Point(acW / 2, acH - acW), true)); arc.Point = new Point(acW, acH - acW / 2); arc.Size = new Size(acW / 2, acW / 2); ps.Add(arc); break; case LineflowStyle.Vertical_Left_Right: figure.StartPoint = new Point(0, acW / 2); arc.Point = new Point(acW / 2, acW); arc.Size = new Size(acW / 2, acW / 2); arc.SweepDirection = SweepDirection.Clockwise;// ps.Add(arc); ps.Add(new LineSegment(new Point(acW / 2, acH - acW), true)); //底部弧度 arc = new ArcSegment(); arc.Point = new Point(acW, acH - acW / 2); arc.Size = new Size(acW / 2, acW / 2); ps.Add(arc); break; case LineflowStyle.Vertical_Right_Left: figure.StartPoint = new Point(acW, acW / 2); arc.Point = new Point(acW / 2, acW); arc.Size = new Size(acW / 2, acW / 2); ps.Add(arc); ps.Add(new LineSegment(new Point(acW / 2, acH - acW), true)); //底部弧度 arc = new ArcSegment(); arc.Point = new Point(0, acH - acW / 2); arc.Size = new Size(acW / 2, acW / 2); arc.SweepDirection = SweepDirection.Clockwise;// ps.Add(arc); break; case LineflowStyle.Vertical_Left_Left: figure.StartPoint = new Point(0, acW / 2); arc.Point = new Point(acW / 2, acW); arc.Size = new Size(acW / 2, acW / 2); arc.SweepDirection = SweepDirection.Clockwise;// ps.Add(arc); ps.Add(new LineSegment(new Point(acW / 2, acH - acW), true)); //底部弧度 arc = new ArcSegment(); arc.Point = new Point(0, acH - acW / 2); arc.Size = new Size(acW / 2, acW / 2); arc.SweepDirection = SweepDirection.Clockwise;// ps.Add(arc); break; case LineflowStyle.Vertical_Right_Right: figure.StartPoint = new Point(acW, acW / 2); arc.Point = new Point(acW / 2, acW); arc.Size = new Size(acW / 2, acW / 2); ps.Add(arc); ps.Add(new LineSegment(new Point(acW / 2, acH - acW), true)); //底部弧度 arc = new ArcSegment(); arc.Point = new Point(acW, acH - acW / 2); arc.Size = new Size(acW / 2, acW / 2); ps.Add(arc); break; #endregion default: break; #endregion } figure.Segments = ps; pathGeometry.Figures.Add(figure); linePath.Data = pathGeometry; } } public class LineflowModel { public double UcWidth { get; set; } public double UcHeight { get; set; } } /// <summary> /// 线条方向枚举 /// </summary> public enum LiquidDirection { /// <summary> /// The none /// </summary> None, /// <summary> /// The forward /// </summary> Forward, /// <summary> /// The backward /// </summary> Backward } /// <summary> /// 线条流动样式 /// </summary> public enum LineflowStyle { /// <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 horizontal tilt up /// </summary> Horizontal_Tilt_Up, /// <summary> /// 向下倾斜The horizontal tilt down /// </summary> Horizontal_Tilt_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, /// <summary> /// 向左倾斜The vertical tilt /// </summary> Vertical_Tilt_Left, /// <summary> /// 向右倾斜The vertical tilt right /// </summary> Vertical_Tilt_Right } }