Datatrigger 上的旋转动画仅触发一次 WPF

问题描述 投票:0回答:1

我的窗口中显示一条带有箭头的路径,他应根据属性“BarcodeScanne.MovementDirection”旋转,但是动画仅在值更改时播放,然后在第二个值更改时播放。谁能提示我我缺少什么:

<Path Data="M12,7L17,12H14V16H10V12H7L12,7M19,21H5A2,2 0 0,1 3,19V5A2,2 0 0,1 5,3H19A2,2 0 0,1 21,5V19A2,2 0 0,1 19,21M19,19V5H5V19H19Z">
<Path.Style>
    <Style TargetType="Path" BasedOn="{StaticResource {x:Type Path}}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding BarcodeScanner.MovementDirection}" Value="Stay">
                <Setter Property="Visibility" Value="Hidden"/>
            </DataTrigger>
            <DataTrigger Binding="{Binding BarcodeScanner.MovementDirection}" Value="Up">
                <DataTrigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="(Path.RenderTransform).(RotateTransform.Angle)" To="0" Duration="0:0:0.2" />
                        </Storyboard>
                    </BeginStoryboard>
                </DataTrigger.EnterActions>
            </DataTrigger>
            <DataTrigger Binding="{Binding BarcodeScanner.MovementDirection}" Value="Down">
                <DataTrigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="(Path.RenderTransform).(RotateTransform.Angle)" To="180" Duration="0:0:0.2" />
                        </Storyboard>
                    </BeginStoryboard>
                </DataTrigger.EnterActions>
            </DataTrigger>
            <DataTrigger Binding="{Binding BarcodeScanner.MovementDirection}" Value="Left">
                <DataTrigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="(Path.RenderTransform).(RotateTransform.Angle)" To="-90" Duration="0:0:0.2" />
                        </Storyboard>
                    </BeginStoryboard>
                </DataTrigger.EnterActions>
            </DataTrigger>
            <DataTrigger Binding="{Binding BarcodeScanner.MovementDirection}" Value="Right">
                <DataTrigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard>
                            <DoubleAnimation Storyboard.TargetProperty="(Path.RenderTransform).(RotateTransform.Angle)" To="90" Duration="0:0:0.2" />
                        </Storyboard>
                    </BeginStoryboard>
                </DataTrigger.EnterActions>
            </DataTrigger>
        </Style.Triggers>
        <Setter Property="RenderTransformOrigin" Value="0.5, 0.5"/>
        <Setter Property="RenderTransform">
            <Setter.Value>
                <RotateTransform Angle="0"/>
            </Setter.Value>
        </Setter>
    </Style>
</Path.Style>
wpf xaml storyboard
1个回答
0
投票

为了获得从当前角度到新目标角度的平滑旋转,我建议使用如下所示的附加属性,该属性在 UIElement 的 RenderTransform 中运行 RotateTransform 的 Angle 属性的动画。

public class AnimatedRotation
{
    public static double Speed { get; set; } = 0.5; // seconds for full circle

    public static readonly DependencyProperty TargetAngleProperty =
        DependencyProperty.RegisterAttached(
            "TargetAngle", typeof(double), typeof(AnimatedRotation),
            new PropertyMetadata(0d, TargetAnglePropertyChanged));

    public static double GetTargetAngle(UIElement element)
    {
        return (double)element.GetValue(TargetAngleProperty);
    }

    public static void SetTargetAngle(UIElement element, double value)
    {
        element.SetValue(TargetAngleProperty, value);
    }

    private static void TargetAnglePropertyChanged(
        DependencyObject o, DependencyPropertyChangedEventArgs args)
    {
        if (o is UIElement element)
        {
            var transform = element.RenderTransform as RotateTransform;
            var currentAngle = transform != null ? transform.Angle : 0;
            var relativeRotation = ((double)args.NewValue - currentAngle - 180) % 360 + 180;

            if (transform == null || transform.IsFrozen)
            {
                transform = new RotateTransform(currentAngle);
                element.RenderTransform = transform;
            }

            transform.BeginAnimation(
                RotateTransform.AngleProperty,
                new DoubleAnimation
                {
                    By = relativeRotation,
                    Duration = TimeSpan.FromSeconds(Speed * Math.Abs(relativeRotation) / 360)
                });
        }
    }
}

您可以将它与 DataTriggers 一起使用,如下所示:

<Style TargetType="Path">
    <Style.Triggers>
        <DataTrigger Binding="{Binding BarcodeScanner.MovementDirection}" Value="Up">
            <Setter Property="local:AnimatedRotation.TargetAngle" Value="0"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding BarcodeScanner.MovementDirection}" Value="Down">
            <Setter Property="local:AnimatedRotation.TargetAngle" Value="180"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding BarcodeScanner.MovementDirection}" Value="Left">
            <Setter Property="local:AnimatedRotation.TargetAngle" Value="270"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding BarcodeScanner.MovementDirection}" Value="Right">
            <Setter Property="local:AnimatedRotation.TargetAngle" Value="90"/>
        </DataTrigger>
    </Style.Triggers>
    <Setter Property="RenderTransformOrigin" Value="0.5, 0.5"/>
</Style>
© www.soinside.com 2019 - 2024. All rights reserved.