| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- using Avalonia;
- using Avalonia.Controls;
- using Avalonia.Media;
- using Avalonia.Threading;
- using System;
- namespace YZWater.Avalonia.Controls;
- /// <summary>
- /// 绠¢亾鎺т欢 - 妯℃嫙 PipeLine
- /// </summary>
- public class PipeLineControl : Control
- {
- public static readonly StyledProperty<bool> IsFlowProperty =
- AvaloniaProperty.Register<PipeLineControl, bool>(nameof(IsFlow), false);
- public static readonly StyledProperty<double> FlowSpeedProperty =
- AvaloniaProperty.Register<PipeLineControl, double>(nameof(FlowSpeed), 1.0);
- public static readonly StyledProperty<IBrush> PipeColorProperty =
- AvaloniaProperty.Register<PipeLineControl, IBrush>(nameof(PipeColor), new SolidColorBrush(Color.Parse("#4CAF50")));
- public static readonly StyledProperty<IBrush> WaterColorProperty =
- AvaloniaProperty.Register<PipeLineControl, IBrush>(nameof(WaterColor), new SolidColorBrush(Color.Parse("#2196F3")));
- public static readonly StyledProperty<double> PipeWidthProperty =
- AvaloniaProperty.Register<PipeLineControl, double>(nameof(PipeWidth), 20.0);
- public static readonly StyledProperty<bool> IsHorizontalProperty =
- AvaloniaProperty.Register<PipeLineControl, bool>(nameof(IsHorizontal), true);
- public bool IsFlow
- {
- get => GetValue(IsFlowProperty);
- set => SetValue(IsFlowProperty, value);
- }
- public double FlowSpeed
- {
- get => GetValue(FlowSpeedProperty);
- set => SetValue(FlowSpeedProperty, value);
- }
- public IBrush PipeColor
- {
- get => GetValue(PipeColorProperty);
- set => SetValue(PipeColorProperty, value);
- }
- public IBrush WaterColor
- {
- get => GetValue(WaterColorProperty);
- set => SetValue(WaterColorProperty, value);
- }
- public double PipeWidth
- {
- get => GetValue(PipeWidthProperty);
- set => SetValue(PipeWidthProperty, value);
- }
- public bool IsHorizontal
- {
- get => GetValue(IsHorizontalProperty);
- set => SetValue(IsHorizontalProperty, value);
- }
- private double _flowOffset = 0;
- private IDisposable? _timerSubscription;
- static PipeLineControl()
- {
- AffectsRender<PipeLineControl>(IsFlowProperty, FlowSpeedProperty, PipeColorProperty, WaterColorProperty, PipeWidthProperty, IsHorizontalProperty);
- }
- protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
- {
- base.OnAttachedToVisualTree(e);
- if (IsFlow)
- {
- StartAnimation();
- }
- }
- protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e)
- {
- base.OnDetachedFromVisualTree(e);
- StopAnimation();
- }
- protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
- {
- base.OnPropertyChanged(change);
- if (change.Property == IsFlowProperty)
- {
- if (IsFlow)
- {
- StartAnimation();
- }
- else
- {
- StopAnimation();
- _flowOffset = 0;
- }
- }
- }
- private void StartAnimation()
- {
- StopAnimation();
- _timerSubscription = DispatcherTimer.Run(() =>
- {
- _flowOffset += FlowSpeed;
- if (_flowOffset >= 20) _flowOffset -= 20;
- InvalidateVisual();
- return true; // 缁х画杩愯
- }, TimeSpan.FromMilliseconds(50));
- }
- private void StopAnimation()
- {
- _timerSubscription?.Dispose();
- _timerSubscription = null;
- }
- public override void Render(DrawingContext context)
- {
- base.Render(context);
- var bounds = new Rect(Bounds.Size);
- var pipeWidth = PipeWidth;
- if (IsHorizontal)
- {
- // 缁樺埗姘村钩绠¢亾
- var pipeRect = new Rect(0, (bounds.Height - pipeWidth) / 2, bounds.Width, pipeWidth);
- context.DrawRectangle(PipeColor, null, pipeRect);
- // 缁樺埗娴佸姩鏁堟灉
- if (IsFlow)
- {
- var dashPen = new Pen(WaterColor, pipeWidth * 0.6, new DashStyle(new double[] { 8, 12 }, _flowOffset));
- var y = bounds.Height / 2;
- context.DrawLine(dashPen, new Point(0, y), new Point(bounds.Width, y));
- }
- }
- else
- {
- // 缁樺埗鍨傜洿绠¢亾
- var pipeRect = new Rect((bounds.Width - pipeWidth) / 2, 0, pipeWidth, bounds.Height);
- context.DrawRectangle(PipeColor, null, pipeRect);
- // 缁樺埗娴佸姩鏁堟灉
- if (IsFlow)
- {
- var dashPen = new Pen(WaterColor, pipeWidth * 0.6, new DashStyle(new double[] { 8, 12 }, _flowOffset));
- var x = bounds.Width / 2;
- context.DrawLine(dashPen, new Point(x, 0), new Point(x, bounds.Height));
- }
- }
- }
- protected override Size MeasureOverride(Size availableSize)
- {
- return IsHorizontal ? new Size(80, 30) : new Size(30, 80);
- }
- }
|