wpf - WPF-顺序动画简单示例

标签 wpf animation storyboard

我正在学习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/

相关文章:

ios - Storyboard - 运行应用程序时图像尺寸太大

wpf - 如何分离wpf文本框中的背景图像?

c# - 如何使用 C# 确定屏幕宽度/高度

angularjs - 带有 css3 过渡的 Angular 淡入淡出动画

Android绘制动画虚线曲线

ios - 应用程序尝试使用 Storyboard以模态方式呈现事件 Controller

c# - 如果 DataContext 来自托管窗口,如何修改 UserControl 中绑定(bind)的 ObservableCollection?

wpf - 如何更改按钮的背景色?

android - 旋转动画速度

ios - 以编程方式覆盖 Storyboard 引用?