using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;
namespace SWRIS.Controls
{
///
/// RopeControl.xaml 的交互逻辑
///
public partial class RopeEquipmentControl : UserControl
{
private Canvas _ropeCanvas; // 添加Canvas引用
private readonly Storyboard _animationStoryboard;
public RopeEquipmentControl()
{
InitializeComponent();
// 初始化动画
_animationStoryboard = (Storyboard)Resources["RopeAnimation"];
// 设置初始动画值
UpdateAnimationValues();
// 订阅SizeChanged事件
SizeChanged += RopeEquipmentControl_SizeChanged;
// 订阅Loaded事件,确保控件加载完成后获取正确的尺寸
Loaded += RopeEquipmentControl_Loaded;
}
#region 依赖属性
// 绳索高度
public static readonly DependencyProperty RopeHeightProperty =
DependencyProperty.Register("RopeHeight", typeof(double), typeof(RopeEquipmentControl),
new PropertyMetadata(900.0));
// 绳索图片
public static readonly DependencyProperty RopeImageSourceProperty =
DependencyProperty.Register("RopeImageSource", typeof(ImageSource), typeof(RopeEquipmentControl));
// 设备图片
public static readonly DependencyProperty EquipmentImageSourceProperty =
DependencyProperty.Register("EquipmentImageSource", typeof(ImageSource), typeof(RopeEquipmentControl));
// 是否运行动画
public static readonly DependencyProperty IsAnimationRunningProperty =
DependencyProperty.Register("IsAnimationRunning", typeof(bool), typeof(RopeEquipmentControl),
new PropertyMetadata(false, OnIsAnimationRunningChanged));
// 动画方向(正向/反向)
public static readonly DependencyProperty IsAnimationReversedProperty =
DependencyProperty.Register("IsAnimationReversed", typeof(bool), typeof(RopeEquipmentControl),
new PropertyMetadata(false, OnAnimationDirectionChanged));
// 动画速度(秒)
public static readonly DependencyProperty AnimationDurationProperty =
DependencyProperty.Register("AnimationDuration", typeof(double), typeof(RopeEquipmentControl),
new PropertyMetadata(0.5, OnAnimationDurationChanged));
// 数据面板位置
public static readonly DependencyProperty PanelMarginProperty =
DependencyProperty.Register("PanelMargin", typeof(Thickness), typeof(RopeEquipmentControl));
// 数据面板文字大小
public static readonly DependencyProperty PanelNameFontSizeProperty =
DependencyProperty.Register("PanelNameFontSize", typeof(double), typeof(RopeEquipmentControl),
new PropertyMetadata(28d));
// 数据面板文字大小
public static readonly DependencyProperty PanelValueFontSizeProperty =
DependencyProperty.Register("PanelValueFontSize", typeof(double), typeof(RopeEquipmentControl),
new PropertyMetadata(28d));
// 设备图片位置
public static readonly DependencyProperty EquipmentTopPositionProperty =
DependencyProperty.Register("EquipmentTopPosition", typeof(double), typeof(RopeEquipmentControl));
#endregion
#region 属性包装器
public double RopeHeight
{
get => (double)GetValue(RopeHeightProperty);
set => SetValue(RopeHeightProperty, value);
}
public ImageSource RopeImageSource
{
get => (ImageSource)GetValue(RopeImageSourceProperty);
set => SetValue(RopeImageSourceProperty, value);
}
public ImageSource EquipmentImageSource
{
get => (ImageSource)GetValue(EquipmentImageSourceProperty);
set => SetValue(EquipmentImageSourceProperty, value);
}
public bool IsAnimationRunning
{
get => (bool)GetValue(IsAnimationRunningProperty);
set => SetValue(IsAnimationRunningProperty, value);
}
public bool IsAnimationReversed
{
get => (bool)GetValue(IsAnimationReversedProperty);
set => SetValue(IsAnimationReversedProperty, value);
}
public double AnimationDuration
{
get => (double)GetValue(AnimationDurationProperty);
set => SetValue(AnimationDurationProperty, value);
}
public Thickness PanelMargin
{
get => (Thickness)GetValue(PanelMarginProperty);
set => SetValue(PanelMarginProperty, value);
}
public double PanelNameFontSize
{
get => (double)GetValue(PanelNameFontSizeProperty);
set => SetValue(PanelNameFontSizeProperty, value);
}
public double PanelValueFontSize
{
get => (double)GetValue(PanelValueFontSizeProperty);
set => SetValue(PanelValueFontSizeProperty, value);
}
public double EquipmentTopPosition
{
get => (double)GetValue(EquipmentTopPositionProperty);
set => SetValue(EquipmentTopPositionProperty, value);
}
#endregion
#region 事件处理
private void RopeEquipmentControl_Loaded(object sender, RoutedEventArgs e)
{
// 控件加载完成后更新RopeHeight
UpdateRopeHeight();
}
private void RopeEquipmentControl_SizeChanged(object sender, SizeChangedEventArgs e)
{
// 当控件大小改变时更新RopeHeight
UpdateRopeHeight();
}
///
/// 更新绳索高度以适应容器大小
///
private void UpdateRopeHeight()
{
try
{
// 获取Canvas引用
if (_ropeCanvas == null)
{
_ropeCanvas = FindName("RopeCanvas") as Canvas;
if (_ropeCanvas == null)
{
// 如果找不到Canvas,使用控件自身高度
RopeHeight = Math.Max(0, ActualHeight);
return;
}
}
// 使用Canvas的实际高度减去上下边距
double newHeight = _ropeCanvas.ActualHeight;
// 确保高度不为负数
if (newHeight < 0)
{
newHeight = 0;
}
// 只有当高度变化时才更新,避免不必要的重新渲染
if (Math.Abs(RopeHeight - newHeight) > 0.1)
{
RopeHeight = newHeight;
}
}
catch (Exception)
{
// 出错时使用备用方案:使用控件自身高度
try
{
RopeHeight = Math.Max(0, ActualHeight);
}
catch
{
// 如果还出错,使用默认值
RopeHeight = 900.0;
}
}
}
#endregion
#region 动画控制
private static void OnIsAnimationRunningChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (RopeEquipmentControl)d;
control.UpdateAnimationState();
}
private static void OnAnimationDirectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (RopeEquipmentControl)d;
control.UpdateAnimationValues();
}
private static void OnAnimationDurationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (RopeEquipmentControl)d;
control.UpdateAnimationValues();
}
private void UpdateAnimationValues()
{
var rectAnimation = (RectAnimation)_animationStoryboard.Children[0];
rectAnimation.Duration = TimeSpan.FromSeconds(AnimationDuration);
if (IsAnimationReversed)
{
rectAnimation.From = new Rect(0, -22, 26, 22);
rectAnimation.To = new Rect(0, 0, 26, 22);
}
else
{
rectAnimation.From = new Rect(0, 0, 26, 22);
rectAnimation.To = new Rect(0, -22, 26, 22);
}
if (IsAnimationRunning)
{
_animationStoryboard.Begin(this, true);
}
}
private void UpdateAnimationState()
{
if (IsAnimationRunning)
{
_animationStoryboard.Begin(this, true);
}
else
{
_animationStoryboard.Stop(this);
}
}
#endregion
#region 公共方法
public void StartAnimation(bool reversed = false)
{
IsAnimationReversed = reversed;
IsAnimationRunning = true;
}
public void StopAnimation()
{
IsAnimationRunning = false;
}
public void ReverseAnimation()
{
IsAnimationReversed = !IsAnimationReversed;
}
#endregion
}
}