如何允许完整的 WPF 故事板动画

Posted

技术标签:

【中文标题】如何允许完整的 WPF 故事板动画【英文标题】:How to allow complete WPF storyboard animation 【发布时间】:2020-11-04 12:48:01 【问题描述】:

我有以下动画。当用户将鼠标悬停在 80px 高的顶部栏时,TranslateTransform 会下拉它。我尝试在后面的代码中执行此操作,但只能在 XAML 中执行此操作。 我遇到的问题 - 我怎样才能让动画在反向动画触发之前完成。例如,用户将鼠标悬停在顶部栏上,它会下降,但在动画完成之前,光标离开该区域并触发反向动画。我想这可以通过一些全局变量来完成,但我不能让动画在后面的代码中工作。

这里是顶栏触发器。

 <Border DockPanel.Dock="Top" x:Name="TopBar" BorderBrush="Wheat" Panel.ZIndex="999">
            <Border.RenderTransform>
                <TransformGroup>
                    <ScaleTransform/>
                    <SkewTransform/>
                    <RotateTransform/>
                    <TranslateTransform Y="-80"/>
                </TransformGroup>
            </Border.RenderTransform>
        <Border.Triggers>
            <EventTrigger RoutedEvent="UIElement.MouseEnter">
                <BeginStoryboard x:Name="OnMouseEnterTopBar_BeginStoryboard" Storyboard="StaticResource OnMouseEnterTopBar"/>
            </EventTrigger>
            <EventTrigger RoutedEvent="UIElement.MouseLeave">
                <BeginStoryboard x:Name="OnMouseLeaveTopBar_BeginStoryboard" Storyboard="StaticResource OnMouseLeaveTopBar"/>
            </EventTrigger>
        </Border.Triggers>

故事板:

<Storyboard x:Key="OnMouseEnterTopBar">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="TopBar">
            <EasingDoubleKeyFrame KeyTime="0" Value="-80"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="0"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>
    <Storyboard x:Key="OnMouseLeaveTopBar">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.Y)" Storyboard.TargetName="TopBar">
            <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
            <EasingDoubleKeyFrame KeyTime="0:0:0.1" Value="-80"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>

这是我在后面的代码中重现 XAML 代码的尝试,但由于某种原因动画太快了,不管我将什么值作为持续时间。

Storyboard storyboard = new Storyboard();
        TranslateTransform scale = new TranslateTransform(0, -80);
        TopBar.RenderTransformOrigin = new Point(0, 0);
        TopBar.RenderTransform = scale;


        DoubleAnimation growAnimation = new DoubleAnimation();
        growAnimation.Duration = TimeSpan.FromSeconds(2);
        growAnimation.From = 1;
        growAnimation.To = 1.8;
        growAnimation.AutoReverse = true;
        growAnimation.RepeatBehavior = RepeatBehavior.Forever;
        storyboard.Children.Add(growAnimation);

        Storyboard.SetTargetProperty(growAnimation, new PropertyPath(TranslateTransform.YProperty));
        Storyboard.SetTarget(growAnimation, TopBar);

        storyboard.Begin();

【问题讨论】:

当您在 XAML 中有一个 DoubleAnimationUsingKeyFrames 动画从 -80 到 0 时,不清楚为什么您认为代码中应该有 DoubleAnimation 动画从 1 到 1.8。还不清楚为什么您认为在代码中创建的动画与在 XAML 中创建的动画的行为不同。尝试在 XAML 中使用 DoubleAnimations 而不是 DoubleAnimationUsingKeyFrames,后者仅设置其 To 属性,从而使它们从动画属性的当前值开始,而不是 From 值。 您还可以通过删除 TransformGroup 并将 TranslateTransform 直接放入 Border 的 RenderTransform 来简化您的 XAML。 【参考方案1】:

我找到了解决问题的方法。 如果我们删除“From”部分,每当我们改变动作鼠标进入/离开时,它都会从那个确切的点相应地改变方向,而不会跳转到“From”中指定的起点。

【讨论】:

以上是关于如何允许完整的 WPF 故事板动画的主要内容,如果未能解决你的问题,请参考以下文章

隐藏受影响的控件时,WPF 故事板动画是不是继续运行?

如何为 WPF 故事板中的静态对象设置动画

故事板 EllipseGeometry 动画

向“切换”发送垃圾邮件时,C#/WPF 处理活动的故事板动画

C#WPF停止故事板

如何让动画从悬停开始 - 故事板