简体   繁体   English

如何使故事板淡入,暂停,然后淡出(通过代码)?

[英]How can I make a storyboard fade in, pause, and then fade out (through code)?

I wrote the following code. 我写了以下代码。 It tries to create a storyboard that does the following: 它尝试创建一个执行以下操作的故事板:

  1. fade in for 500ms 淡入500ms
  2. pause for 1000ms 暂停1000ms
  3. fade out for 500ms 淡出500ms

But at run time get an System.InvalidOperationException followed by the following output: 但是在运行时获取System.InvalidOperationException,后跟以下输出:

Additional information: Multiple animations in 
  the same containing Storyboard cannot target the
  same property on a single element.

This seems to suggest its trying to do all the animations at once rather than sequentially. 这似乎表明它试图一次完成所有动画,而不是顺序完成。

private Storyboard createStoryboard()
{
  Storyboard board = new Storyboard();

  addFadeToStoryboard(board, 0, 1, 500);
  addFadeToStoryboard(board, 1, 1, 1000);

  DoubleAnimation fadeOut = addFadeToStoryboard(board, 1, 0, 500);

  fadeOut.Completed += new EventHandler(onFadeCompleted);

  Storyboard.SetTarget(board, this);

  return board;
}

private DoubleAnimation addFadeToStoryboard(Storyboard board, 
  double fadeFrom, double fadeTo, double milliseconds)
{
  DoubleAnimation fade = new DoubleAnimation()
  {
    Duration = new Duration(TimeSpan.FromMilliseconds(milliseconds)),
    From = fadeFrom,
    To = fadeTo,
    RepeatBehavior = new RepeatBehavior(1)
  };

  Storyboard.SetTargetProperty(fade,
    new PropertyPath(UIElement.OpacityProperty));

  board.Children.Add(fade);

  return fade;
}

How can I make it sequential? 我怎样才能顺序完成? Am I misinterpreting something fundamental about storyboards? 我是否误解了故事板的基本内容?

Thanks 谢谢

If the storyboard contains multiple animations they all get started at the same time and run simultaneously. 如果故事板包含多个动画,则它们全部同时启动并同时运行。 You can set the BeginTime property on the DoubleAnimations to a TimeSpan to indicate when they should begin...so by passing in an accumulative time of all the previous animations you should be able to get the sequential effect. 您可以将DoubleAnimations上的BeginTime属性设置为TimeSpan以指示它们应该何时开始...因此,通过传入所有先前动画的累积时间,您应该能够获得顺序效果。

EDIT: Sorry - I just noticed the Silverlight tag. 编辑:对不起 - 我刚刚注意到Silverlight标签。 My answer works in WPF...I don't know about the differences between Silverlight and WPF animations. 我的答案适用于WPF ...我不知道Silverlight和WPF动画之间的区别。

This might help. 可能有所帮助。 It looks like it is a difference between WPF and Silverlight. 它看起来像是WPF和Silverlight之间的区别。 Where WPF can handle animating the same property on different animations in the same storyboard, Silverlight doesn't. WPF可以在同一个故事板中处理不同动画上的相同属性的动画,而Silverlight则不然。 Instead of having separate DoubleAnimations they suggest using a single DoubleAnimationUsingKeyFrames...then each of your separate animations becomes a key frame within it and it should animate linearly between them. 他们建议使用单个DoubleAnimationUsingKeyFrames而不是单独的DoubleAnimations ...然后每个单独的动画成为其中的关键帧,它应该在它们之间线性动画。

I've solved this by creating my own sequencer class. 我通过创建自己的sequencer类来解决这个问题。 It has a dependency on a LinkedList class, so you'll have to swap that out with the standard one if you want to use this code: 它依赖于LinkedList类,因此如果要使用此代码,则必须将其与标准类交换:

using System;
using System.Windows.Media.Animation;

namespace YourNamespace
{
  // An object that contains multiple storyboards, and fires off 
  // subsequent ones as they finish.

  public class StoryboardSequencer
  {
    public StoryboardSequencer()
    {
    }

    public void add(Storyboard board)
    {
      m_boards.add(board);
      board.Completed += new EventHandler(onBoardCompleted);
    }

    // Starts the storyboard from the first.
    // If already started, this call is ignored.
    public void begin()
    {
      if (m_boards.size() > 0)
      {
        m_currentBoardIndex = 0;
        beginCurrentBoard();
      }
      else
      {
        onLastBoardCompleted();
      }
    }

    // Stops and rewinds.
    // Does not call completed handler.
    public void stop()
    {
      if (m_currentBoardIndex != -1)
      {
        Storyboard board = m_boards.get(m_currentBoardIndex);
        if (board != null)
        {
          board.Stop();
        }

        m_currentBoardIndex = -1;
      }
    }

    private void beginCurrentBoard()
    {
      Storyboard board = m_boards.get(m_currentBoardIndex);
      if (board == null)
      {
        onLastBoardCompleted();
      }
      else
      {
        board.Begin();
      }
    }

    // Triggered when the sequence completes.
    public event EventHandler Completed;

    private void onBoardCompleted(object sender, EventArgs e)
    {
      m_currentBoardIndex++;

      if (m_currentBoardIndex >= m_boards.size())
      {
        onLastBoardCompleted();
      }
      else
      {
        beginCurrentBoard();
      }
    }

    private void onLastBoardCompleted()
    {
      m_currentBoardIndex = -1;
      Completed.Invoke(this, null);
    }

    private LinkedList<Storyboard> m_boards = new LinkedList<Storyboard>();

    // The current storyboard playing, or -1 if none.
    private int m_currentBoardIndex = -1;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM