【问题标题】:Converting UWP XAML animation to C#将 UWP XAML 动画转换为 C#
【发布时间】:2016-08-18 20:34:06
【问题描述】:

我有一个有效的 XAML 动画,用于为类似里程表的数字设置动画。我需要制作六个几乎相同但不同的动画版本。据我所知,没有一种以这种方式重用动画 XAML 的好方法,因此为了保持代码干燥,我转向了动画的程序化创建。

在尝试将此 XAML 动画转换为 C# 时,我遇到了无法找到目标的问题:

未检测到已安装的组件。\r\n\r\n无法解析 TargetName Digit1。

如果我调用 Storyboard.SetTarget() 而不是 Storyboard.SetTargetName() 我不再收到此异常,但屏幕上仍然没有任何反应。

谁能告诉我我在这个翻译中做错了什么?

XAML:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      mc:Ignorable="d">

    <Page.Resources>
        <x:Double x:Key="OdometerMoveUpDistance">-101</x:Double>

        <Storyboard x:Name="OdometerUpStoryboard">
            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
                                           Storyboard.TargetName="Digit1">
                <EasingDoubleKeyFrame KeyTime="0" Value="0" />
                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="{StaticResource OdometerMoveUpDistance}" />
            </DoubleAnimationUsingKeyFrames>
        </Storyboard>
    </Page.Resources>

    <Canvas x:Name="Odometer" Width="100" Height="100">
        <TextBlock x:Name="Digit1" FontSize="100" Text="8">
            <TextBlock.RenderTransform><CompositeTransform /></TextBlock.RenderTransform>
        </TextBlock>
    </Canvas>

</Page>

C#:

private void Btn_Click(object sender, RoutedEventArgs e)
{
    DoubleAnimationUsingKeyFrames digitUp = CreateOdometerdigitAnim(this.Digit1, 0, -101);

    var storyboard = new Storyboard();
    storyboard.Children.Add(digitUp);
    storyboard.Begin(); // Exception happens on this line
}

private DoubleAnimationUsingKeyFrames CreateOdometerdigitAnim(TextBlock digit, double startPos, double endPos)
{
    var start = new EasingDoubleKeyFrame();
    start.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(0));
    start.Value = startPos;

    var end = new EasingDoubleKeyFrame();
    end.KeyTime = KeyTime.FromTimeSpan(TimeSpan.FromMilliseconds(1000));
    end.Value = endPos;

    var anim = new DoubleAnimationUsingKeyFrames();
    anim.KeyFrames.Add(start);
    anim.KeyFrames.Add(end);

    Storyboard.SetTargetProperty(anim, "(UIElement.RenderTransform).(CompositeTransform.TranslateY)");
    Storyboard.SetTargetName(anim, digit.Name);

    /* Using SetTarget instead of SetTargetName throws no exception but still does not animate */
    // Storyboard.SetTarget(anim, digit);

    return anim;
}

【问题讨论】:

  • 这可以是 PITA。通常,如果我需要与代码隐藏中的动画进行交互,我会做什么,我只是将它定义为 xaml 中的资源,然后从我的代码隐藏中的资源中获取动画。省去转换的麻烦。

标签: c# xaml animation uwp uwp-xaml


【解决方案1】:

如果我调用 Storyboard.SetTarget() 而不是 Storyboard.SetTargetName(),我将不再收到此异常,但屏幕上仍然没有任何反应。

你需要给Digit1.RenderTransform一个CompositeTransform对象。您可以在 XAML 或代码隐藏中执行此操作:

如果在 XAML 中:

<TextBlock x:Name="Digit1" FontSize="100" Text="8">
    <TextBlock.RenderTransform>
        <CompositeTransform />
    </TextBlock.RenderTransform>
</TextBlock>

如果在 Code-Behind 中,请在 storyboard.Begin() 之前添加代码,如下所示:

Digit1.RenderTransform = new CompositeTransform();
...
storyboard.Begin();

在尝试将此 XAML 动画转换为 C# 时,我遇到了无法找到目标的问题:

未检测到已安装的组件。\r\n\r\n无法解析 TargetName Digit1。

我可以用您的代码重现问题。我用 XAML 定义的 StoryBoard+Animation 进行了尝试,一切正常。稍后需要通过内部渠道进行一些确认。

【讨论】:

  • 非常感谢您的回复!抱歉,事实证明我的 XAML 中确实有 CompositeTransform,因为 Blend 添加了它,但我不知道它的目的是什么,并且在我的示例中为了简洁而错误地删除了它。我很高兴听到我的问题是可重现的,您可以收集到的有关根本原因的任何信息都会非常有帮助!
  • Storyboard.SetTarget() 现在应该可以正常工作了。对于Storyboard.SetTargetName,我需要通过内部渠道进行确认,如果我有任何回复,我会通知您。
猜你喜欢
  • 1970-01-01
  • 2017-11-25
  • 1970-01-01
  • 1970-01-01
  • 2013-04-26
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
  • 2012-03-21
相关资源
最近更新 更多