我如何使故事板淡入,暂停,然后淡出(通过代码)
本文关键字:淡出 代码 然后 暂停 何使 故事 淡入 | 更新日期: 2023-09-27 18:03:49
我编写了以下代码。它尝试创建一个storyboard,并执行以下操作:
- 渐近500ms
- 暂停1000ms
- 淡出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;
}
}