【问题标题】:UWP Animation resets to From stateUWP 动画重置为 From 状态
【发布时间】:2019-01-14 00:43:13
【问题描述】:

我在 UWP 应用程序中有一个动画,它在 Windows 更新 1809 之前按预期工作(生产 Windows 应用商店应用程序)。发生了一些变化,现在动画在完成后立即重置为 From 值。

示例代码:

动画(旋转):

<Storyboard x:Key="FlipTest">
    <DoubleAnimation
                        Storyboard.TargetName="TestRotation"
                        Storyboard.TargetProperty="RotationY"
                        From="180"
                        To="10"
                        Duration="0:0:1.40"
                        />
</Storyboard>

动画项目:

    <TextBlock Text="Test" FontSize="18">
        <TextBlock.Projection>
            <PlaneProjection x:Name="TestRotation" RotationY="0" />
        </TextBlock.Projection>
    </TextBlock>

从按钮点击开始调用:

private void Button_Click(object sender, RoutedEventArgs e)
{
    Storyboard sb = (Storyboard)Resources["FlipTest"];
    sb.Begin();
}

预期行为(适用于 Windows 1803): 当您单击按钮时,TextBlock 会旋转并保持在此状态。

Windows 1809 上的行为: 动画结束后,但在调用 Storyboard.Completed 事件之前,TextBox 重置为 From(180 度)值。

有趣的是,如果我输入To="0",它会保持这种状态。如果我设置 10、190 或 360 度,它会重置。请注意,它不会重置为原始状态(即 0 度),而是重置为 From 值(180 度)。

我还将Microsoft.NETCore.UniversalWindowsPlatform 更新到最新版本(6.1.9),但没有任何改变。

谁能解释这种行为或告诉如何解决它?我错过了什么明显的东西吗?

更新(丑陋的解决方法)

我发现我可以使用以下丑陋的 hack:

    sb.Completed += (s, ee) =>
    {
        TestRotation.RotationY = 0.01; // ugly hack for Windows Build 1809
    };

但它不仅在代码中看起来很糟糕。在屏幕上你可以看到可怕的 blink,因为在动画之后项目重置,然后再次设置为正常值。

我还注意到 RotationY 在动画完成后保持正确的值,尽管在视觉上项目旋转了。您可以在代码(完整动画)或Live Property Explorer 中看到该值为 0,而在视觉上该项目旋转到 180 度。

【问题讨论】:

  • 我已将此问题报告给相关团队。他们正在调查。
  • 我在 1803 和 1809 上构建时遇到了同样的问题。我已经尝试过其他版本,但我猜这是一个从裂缝中溜走的现有错误;但我相信这是一个错误。

标签: c# animation uwp uwp-xaml


【解决方案1】:

我认为这是一个错误,并与 StoryboardFillBehavior 相关联。

这一直发生在我的第一个 Windows 10 Build 10240 中。由于某种原因,如果结果是 != 0 则使用 FillBehavior.HoldEnd 状态将重置为 From 值而不是 @987654325 @value(Storyboard 结尾的值)。

在没有查看开源代码(这将是最好的 IMO)的情况下,我做了以下事情,这导致我做出了这个假设。

一直到 Windows 10 的第一个版本,都验证了您在 Windows 版本上的现有代码。测试了 To = 10To = 0To = 10 重置为起始 From 值。 To = 0 重置为原始值。您已经记录在案了。

From 值修改为超过To 值360 度(使用随机值),以便它执行完整的旋转。在这一点上它确实停在From 值上,它看起来也像To 值,它只是说Storyboard.FillBehavior = FillBehavior.HoldEnd 保持From 值。我知道这不是Storyboard.FillBehavior = FillBehavior.Stop,因为它每次都会重置为Storyboard 之前的初始值(这是FillBehavior.Stop 应该做的)。

我假设这是基于我所做的各种测试,包括手动编写 Storyboard

假设:

如果Storyboard.FillBehavior = FillBehavior.HoldEndStoryboard.To 的值不为0,那么一旦完成,它将保持Storyboard.From 的值。

如果是Storyboard.FillBehavior = FillBehavior.Stop,那么它会按预期工作并返回到动画之前值所处的任何状态。

建议的解决方法:

虽然我看到您可以通过使用Storyboard.Completed 事件来解决问题,但我还有另一种选择(虽然它仍然不愉快),它可能更清洁并消除闪烁;它对我有用。

我已经设置了TimelinesFillBehavior.Stop 受到影响,然后我将它们动画属性的初始值设置为To 值。

注意:在您的示例中,您的 DoubleAnimation.Duration 大于您的 Storyboard.Duration。这将始终导致它重置为此起始值(在本例中为 From 值),因为 DoubleAnimation 永远不会完成。确保您的 Storyboard.Duration 至少与您的最高子 Timeline 一样长,以防止闪烁和不良影响。

我最初认为这是您的问题,但在将 Storyboard 设置为匹配或更好之后,您的问题仍然存在。只要知道持续时间的差异可能会导致不需要的结果,尤其是当您的 Storyboard 比您的孩子 Timeline(s) 短时。

<Storyboard x:Key="FlipTest"
            Duration="0:0:1.40">
    <DoubleAnimation Storyboard.TargetName="TestRotation"
                     Storyboard.TargetProperty="RotationY"
                     From="180"
                     To="10"
                     Duration="0:0:1.40" 
                     FillBehavior="Stop"/>
</Storyboard>


TestRotation.RotationY = 10;
Storyboard sb = (Storyboard)Resources["FlipTest"];
sb.Begin();

【讨论】:

  • 伟大的研究和伟大的帮助。你得到了赏金!您的解决方法有效!我需要玩一会儿才能弄清楚什么是重要的。对于可能有类似问题的人,我需要指出 3 个关键组件以使解决方法有效: 1. 将故事板持续时间设置为与 DoubleAnimation 中的相同。 2. 只为有问题的 DoubleAnimation 设置FillBehaviour="Stop"(我在Storyboard 中有多个)。 3. 确保PlanProjectionRotationY 值设置为与DoubleAnimation 中的To 值相同(这很重要,如果设置为From 仍然会出错)。
猜你喜欢
  • 1970-01-01
  • 2021-09-05
  • 2015-12-24
  • 2019-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-16
  • 2014-02-07
相关资源
最近更新 更多