在Windows Phone应用程序中重用Storyboard

时间:2012-11-11 01:56:12

标签: c# silverlight storyboard windows-phone

我的Windows Phone应用程序中使用了Storyboard

<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>

我有多个Rectangle将使用此Storyboard,但它似乎只是第一次工作

例如,以下代码用于显示四个不同的Rectangles,但仅显示第一个。{1}}。代码没有错误,但最后3 Rectangle没有变为红色,看起来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重复使用?

2 个答案:

答案 0 :(得分: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. 您无法使用单个故事板同时为两个控件设置动画。如果要同时为所有矩形设置动画,则需要为每个控件使用一个故事板。

答案 1 :(得分:1)

我必须再次发表评论,因为我仍然无法发表评论。

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

如果所有其他方法都失败了,您可以创建一个UserControl,其中包含一个矩形,其中包含您可以重复使用的故事板。我在上一个问题中提供的代码示例来自使用故事板翻转的Tile。由于它是一个用户控件,我可以拥有尽可能多的瓷砖,我想同时翻转。