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

本文关键字:淡出 代码 然后 暂停 何使 故事 淡入 | 更新日期: 2023-09-27 18:03:49

我编写了以下代码。它尝试创建一个storyboard,并执行以下操作:

  1. 渐近500ms
  2. 暂停1000ms
  3. 淡出500ms

但是在运行时得到一个System。InvalidOperationException,后面跟着以下输出:

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

这似乎表明,它试图做所有的动画一次,而不是顺序。

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

我怎样才能使它连续?我是否误解了故事板的基本原理?

谢谢

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

如果故事板包含多个动画,它们将同时开始并同时运行。你可以将DoubleAnimations的BeginTime属性设置为一个TimeSpan来指示它们何时开始…因此,通过传入所有先前动画的累计时间,您应该能够获得顺序效果。

编辑:对不起-我只是注意到Silverlight标签。我的答案适用于WPF…我不知道Silverlight和WPF动画之间的区别。

这可能有帮助。看起来这是WPF和Silverlight之间的区别。WPF可以在同一个故事板的不同动画上处理相同的属性,而Silverlight不能。他们建议使用单一的DoubleAnimationUsingKeyFrames,而不是单独的DoubleAnimations。然后,每个单独的动画都成为其中的关键帧,并且它应该在它们之间线性地动画。

我通过创建自己的音序器类来解决这个问题。它依赖于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;
  }
}