我正在学习WPF动画,并对如何顺序应用动画感到困惑。举一个简单的例子,我在一个统一的网格中有四个矩形,并且想要顺序更改每个矩形的颜色。这是我到目前为止的内容:
public partial class Window1 : Window
{
Rectangle blueRect;
Rectangle redRect;
Rectangle greenRect;
Rectangle yellowRect;
public Window1()
{
InitializeComponent();
blueRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Blue, Name="Blue"};
redRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Red, Name="Yellow"};
greenRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Green, Name="Green" };
yellowRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Yellow, Name="Yellow" };
UniformGrid1.Children.Add(blueRect);
UniformGrid1.Children.Add(redRect);
UniformGrid1.Children.Add(greenRect);
UniformGrid1.Children.Add(yellowRect);
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
animateCell(blueRect, Colors.Blue);
animateCell(redRect, Colors.Red);
}
private void animateCell(Rectangle rectangle, Color fromColor)
{
Color toColor = Colors.White;
ColorAnimation ani = new ColorAnimation(toColor, new Duration(TimeSpan.FromMilliseconds(300)));
ani.AutoReverse = true;
SolidColorBrush newBrush = new SolidColorBrush(fromColor);
ani.BeginTime = TimeSpan.FromSeconds(2);
rectangle.Fill = newBrush;
newBrush.BeginAnimation(SolidColorBrush.ColorProperty, ani);
//NameScope.GetNameScope(this).RegisterName(rectangle.Name, rectangle);
//Storyboard board = new Storyboard();
//board.Children.Add(ani);
//Storyboard.SetTargetName(rectangle, rectangle.Name);
//Storyboard.SetTargetProperty(ani, new PropertyPath(SolidColorBrush.ColorProperty));
//board.Begin();
}
最简单的方法是什么?注释中的代码是我的第一个猜测,但无法正常工作。
最佳答案
应该有一个事件ani.Completed
-处理该事件并开始动画的下一个阶段,然后开始运行第一个阶段,每个阶段都将触发下一个阶段。
ColorAnimation ani = // whatever...
ani.Completed += (s, e) =>
{
ColorAnimation ani2 = // another one...
// and so on
};
newBrush.BeginAnimation(SolidColorBrush.ColorProperty, ani);
更新:
public partial class Window1 : Window
{
Rectangle blueRect;
Rectangle redRect;
Rectangle greenRect;
Rectangle yellowRect;
public Window1()
{
InitializeComponent();
blueRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Blue, Name = "Blue" };
redRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Red, Name = "Yellow" };
greenRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Green, Name = "Green" };
yellowRect = new Rectangle() { Fill = System.Windows.Media.Brushes.Yellow, Name = "Yellow" };
UniformGrid1.Children.Add(blueRect);
UniformGrid1.Children.Add(redRect);
UniformGrid1.Children.Add(greenRect);
UniformGrid1.Children.Add(yellowRect);
}
IEnumerable<Action<Action>> AnimationSequence()
{
for (; ; )
{
yield return AnimateCell(blueRect, Colors.Blue);
yield return AnimateCell(redRect, Colors.Red);
yield return AnimateCell(greenRect, Colors.Green);
yield return AnimateCell(yellowRect, Colors.Yellow);
}
}
private IEnumerator<Action<Action>> _actions;
private void RunNextAction()
{
if (_actions.MoveNext())
_actions.Current(RunNextAction);
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
_actions = AnimationSequence().GetEnumerator();
RunNextAction();
}
private Action<Action> AnimateCell(Rectangle rectangle, Color fromColor)
{
return completed =>
{
Color toColor = Colors.White;
ColorAnimation ani = new ColorAnimation(toColor,
new Duration(TimeSpan.FromMilliseconds(300)));
ani.AutoReverse = true;
ani.Completed += (s, e) => completed();
SolidColorBrush newBrush = new SolidColorBrush(fromColor);
ani.BeginTime = TimeSpan.FromSeconds(2);
rectangle.Fill = newBrush;
newBrush.BeginAnimation(SolidColorBrush.ColorProperty, ani);
};
}
}
尝试将以上内容粘贴到您的程序中。它可以满足您的需求,但在其他情况下可能对您有用。它仍然是事件驱动的,但是它使用“迭代器方法”(带有yield return)来创建一种印象,即顺序动画会在动画进行时阻止。
这样做的好处是,您可以以非常直观的方式使用AnimationSequence方法-您可以在一系列语句中写出动画的时间轴,或使用循环,或任何您想要的东西。
关于wpf - WPF-顺序动画简单示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1511870/