3

Storyboard在我的 Windows Phone 应用程序中使用了一个:

<Canvas x:Name="myCanvas" Grid.Row="1">
  <Canvas.Resources>
    <Storyboard x:Name="sb">
      <ColorAnimationUsingKeyFrames 
             Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)"
             AutoReverse="True">
               <EasingColorKeyFrame KeyTime="00:00:0" Value="Black" />
               <EasingColorKeyFrame KeyTime="00:00:0.25" Value="Red" />
      </ColorAnimationUsingKeyFrames>
    </Storyboard>
  </Canvas.Resources>
</Canvas>

我有多个Rectangles 将使用它Storyboard但它似乎只在第一次工作

例如,下面的代码用于显示四个不同Rectangles但只显示第一个。代码没有错误,但最后 3Rectangle秒没有变红,而且看起来Storyboard甚至没有运行。

sb.Stop();
sb.SetValue(Storyboard.TargetNameProperty, myRect1.name);
sb.Begin();

sb.Stop();
sb.SetValue(Storyboard.TargetNameProperty, myRect2.name);
sb.Begin();

sb.Stop();
sb.SetValue(Storyboard.TargetNameProperty, myRect3.name);
sb.Begin();

sb.Stop();
sb.SetValue(Storyboard.TargetNameProperty, myRect4.name);
sb.Begin();

谁能看到我做错了什么,或者知道如何让我Storyboard的可重用?

4

2 回答 2

2

首先,你做错了什么:

故事板执行是异步的。当您调用该Storyboard.Begin方法时,情节提要在后台开始,您的代码将继续执行。因此,您Storyboard.Stop在启动后立即调用!唯一一个你不会停止的是最后一个,这就是为什么它是唯一一个颜色变化的矩形。

如果你想链接你的动画,你必须订阅Completed事件以知道故事板何时结束,然后重新启动它以进行下一个控件。这是一种方法:

private Rectangle[] ControlsToAnimate;

private int CurrentIndex;

private void Button_Click(object sender, RoutedEventArgs e)
{
    this.ControlsToAnimate = new[] { this.Rectangle1, this.Rectangle2 };

    this.Storyboard1.Completed += StoryboardCompleted;
    this.AnimateNextControl();
}

private void AnimateNextControl()
{
    if (this.CurrentIndex >= this.ControlsToAnimate.Length)
    {
        this.CurrentIndex = 0;
        return;
    }

    var nextControl = this.ControlsToAnimate[this.CurrentIndex];

    this.CurrentIndex++;

    this.Storyboard1.Stop();
    this.Storyboard1.SetValue(Storyboard.TargetNameProperty, nextControl.Name);
    this.Storyboard1.Begin();
}

private void StoryboardCompleted(object sender, EventArgs e)
{
    this.AnimateNextControl();
}

现在,您将面临两个问题:

  1. 将情节提要分配给新控件时,前一个控件的颜色将恢复为其原始值(在情节提要开始之前)。如果您希望它保持其新值,则必须保存它:

    private void AnimateNextControl()
    {
        if (this.CurrentIndex > 0)
        {
            var brush = (SolidColorBrush)this.ControlsToAnimate[this.CurrentIndex - 1].Fill;
            brush.Color = brush.Color;
        }
    
        if (this.CurrentIndex >= this.ControlsToAnimate.Length)
        {
            this.CurrentIndex = 0;
            return;
        }
    
        var nextControl = this.ControlsToAnimate[this.CurrentIndex];
    
        this.CurrentIndex++;
    
        this.Storyboard1.Stop();
        this.Storyboard1.SetValue(Storyboard.TargetNameProperty, nextControl.Name);
        this.Storyboard1.Begin();
    }
    
  2. 您不能使用单个情节提要同时为两个控件设置动画。如果要同时为所有矩形设置动画,则需要为每个控件使用一个情节提要。

于 2012-11-11T09:47:15.223 回答
1

我必须再一次让我的评论成为答案,因为我显然仍然无法发表评论。

您是否尝试同时运行所有这些?我确实相信只有一个 XAML 定义的故事板实例存在,因此您可能无法同时在多个控件上重用它。

如果一切都失败了,你可以创建一个包含你可以重复使用的故事板的矩形的 UserControl。我在上一个问题中提供的代码示例来自使用情节提要翻转的 Tile。由于它是一个用户控件,因此我可以同时翻转尽可能多的瓷砖。

于 2012-11-11T08:13:06.593 回答