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
    }
}

  

posted on 2020-09-25 11:55  永恒921  阅读(272)  评论(0编辑  收藏  举报