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