【问题标题】:Animate TransformScale of multiple elements by code: c#通过代码动画化多个元素的TransformScale:c#
【发布时间】:2017-12-15 08:48:20
【问题描述】:

我有一堆这样的网格元素:

<Grid x:Name="LevelSegment6" Opacity="1" Canvas.Left="224" Canvas.Top="109" Width="19" Height="33" Background="{DynamicResource SpiritLevelSegment}" RenderTransformOrigin="0.5,0.5">
     <Grid.RenderTransform>
          <TransformGroup>
               <ScaleTransform CenterX="-1" CenterY="0" ScaleX="0" ScaleY="0"/>
               <RotateTransform Angle="90"/>
          </TransformGroup>
     </Grid.RenderTransform>
</Grid>

这是 24 个网格元素之一。它们都有不同的 Canvas 位置和角度。然而,ScaleX 和 ScaleY 值必须是动画的。

为了测试我编写的所有内容并测试了故事板,如下所示:

<Storyboard x:Key="storyboard">
            <DoubleAnimation Storyboard.TargetName="LevelSegment6" Storyboard.TargetProperty="RenderTransform.Children[0].ScaleX" To="0.3" BeginTime="0:0:0" Duration="0:0:0.5"/>
            <DoubleAnimation Storyboard.TargetName="LevelSegment6" Storyboard.TargetProperty="RenderTransform.Children[0].ScaleY" To="0.6" BeginTime="0:0:0" Duration="0:0:0.5"/>
</Storyboard>

当我启动情节提要时,元素会按预期设置动画,但只有情节提要中定义的一个元素。为了动画化我想要为每个代码创建这个故事板的所有内容,并同时为所有 24 个网格运行 24 个这样的故事板。

这是生成和运行这些故事板的代码:

   DoubleAnimation animx = new DoubleAnimation();
   animx.Duration = TimeSpan.FromSeconds(0.5);
   animx.BeginTime = TimeSpan.FromMilliseconds(0);
   animx.To = 0.5;
   DoubleAnimation animy = new DoubleAnimation();
   animy.Duration = TimeSpan.FromSeconds(0.5);
   animy.BeginTime = TimeSpan.FromMilliseconds(0);
   animy.To = 0.5;

   Storyboard.SetTargetName(animx, "LevelSegment" + i.ToString());
   Storyboard.SetTargetProperty(animx, new PropertyPath("RenderTransform.Children[0].ScaleX"));
   Storyboard.SetTargetName(animy, "LevelSegment" + i.ToString());
   Storyboard.SetTargetProperty(animy, new PropertyPath("RenderTransform.Children[0].ScaleY"));

   Storyboard storyboard = new Storyboard();
   storyboard.Children.Add(animx);
   storyboard.Children.Add(animy);

   storyboard.Begin(this, true);

所有这些显然都在一个 for 循环中,所以我可以遍历所有网格。当我尝试运行它时,它会在“storyboard.Begin(this, true);”处引发错误

“System.InvalidOperationException”并且描述说该对象不支持此属性“RenderTransform.Children[0].ScaleX”。但它应该支持这一点,因为它基本上 100% 与我之前在手动编写的故事板中使用的方法相同。有谁知道这里发生了什么?

【问题讨论】:

  • 请注意,将x:Name 分配给 ScaleTransform 会更简单,例如x:Name="scale1",然后拨打scale1.BeginAnimation(ScaleTransform.ScaleXProperty, animx)。您甚至可以重复使用单个 DoubleAnimation。
  • 你说得对,这将是最简单的解决方法。我总是喜欢通过引用顶级元素来使其尽可能灵活,但在这种情况下,我只需要为比例设置动画,不需要其他任何东西,所以这确实有效。感谢您指出。

标签: c# wpf animation storyboard


【解决方案1】:

我通过将“x:Name”放入 ScaleTransform 而不是网格来修复它:

<Grid Opacity="1" Canvas.Left="224" Canvas.Top="109" Width="19" Height="33" Background="{DynamicResource SpiritLevelSegment}" RenderTransformOrigin="0.5,0.5">
      <Grid.RenderTransform>
           <TransformGroup>
               <ScaleTransform x:Name="LevelSegment6" CenterX="-1" CenterY="0" ScaleX="0" ScaleY="0"/>
               <RotateTransform Angle="90"/>
           </TransformGroup>
      </Grid.RenderTransform>
</Grid>

通过这样做,我还可以直接为属性设置动画,而无需使用情节提要:

DoubleAnimation animx = new DoubleAnimation();
animx.Duration = TimeSpan.FromSeconds(0.5);
animx.BeginTime = TimeSpan.FromMilliseconds(0);
animx.To = 0.3;
DoubleAnimation animy = new DoubleAnimation();
animy.Duration = TimeSpan.FromSeconds(0.5);
animy.BeginTime = TimeSpan.FromMilliseconds(0);
animy.To = 0.6;

ScaleTransform scale = (ScaleTransform)FindName("LevelSegment" + i.ToString());
scale.BeginAnimation(ScaleTransform.ScaleXProperty, animx);
scale.BeginAnimation(ScaleTransform.ScaleYProperty, animy);

【讨论】:

    猜你喜欢
    • 2022-01-05
    • 2011-01-03
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 2013-10-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多