双重动画后的事件同时保持上下文

时间:2012-11-28 03:06:35

标签: c# wpf

我正在尝试创建动画,但在动画发生后执行某些代码时遇到问题。动画代码如下......

public static void Friend(Canvas canvas)
{
    foreach (var element in canvas.Children.OfType<Image>())
    {
        var elementName = Regex.Split(element.Name, "_");
        if (elementName[0] == "friend")
        {
            var slideDown = new DoubleAnimation
                {
                    From = Canvas.GetBottom(element),
                    To = Canvas.GetBottom(element) - element.Height,
                    Duration = new Duration(TimeSpan.FromSeconds(1)),
                    AutoReverse = true
                };
            element.BeginAnimation(Canvas.BottomProperty, slideDown);
            slideDown.Completed += (sender, e) => Test(sender, e, element, canvas);
        }
    }
}

之后发生的事件是......

var random = new Random();
element.Source = Core.StreamImage(Wardrobe.Friends[Wardrobe.RandomFriend()]);
Canvas.SetLeft(element, random.Next(0, (int)(canvas.ActualWidth - element.Width)));
// then reverse the previous animation.

正如您所看到的,事件需要保留动画的上下文以使其工作,但事件处理程序不允许这样做。我尝试直接在element.BeginAnimation下面添加此代码,但它会过早执行。

我也尝试将动画的各个部分拆分成单独的函数,但当然你不能在一个对象上有多个动画,因为函数没有按顺序执行,导致只播放最后一个部分。 / p>

2 个答案:

答案 0 :(得分:0)

尝试在执行上方移动事件

public static void Friend(Canvas canvas)
{
    foreach (var element in canvas.Children.OfType<Image>())
    {
        var elementName = Regex.Split(element.Name, "_");
        if (elementName[0] == "friend")
        {
            var slideDown = new DoubleAnimation
                {
                    From = Canvas.GetBottom(element),
                    To = Canvas.GetBottom(element) - element.Height,
                    Duration = new Duration(TimeSpan.FromSeconds(1)),
                    AutoReverse = true
                };
            slideDown.Completed += (sender, e) => Test(sender, e, element, canvas);
            element.BeginAnimation(Canvas.BottomProperty, slideDown);
        }
    }
}

我不是100%,但我认为动画在执行后变为Freezable,所以我们不能在

之后修改

顺便说一句,你可以在一个对象上有多个动画,但你需要使用&#34; StoryBoard&#34;。

故事板示例:

 var slideDown = new DoubleAnimation { From = 100, To = 200, Duration = new Duration(TimeSpan.FromSeconds(5)), AutoReverse = true };
 var slideLeft = new DoubleAnimation { From = 100, To = 200, BeginTime = TimeSpan.FromSeconds(5), Duration = new Duration(TimeSpan.FromSeconds(5)), AutoReverse = true };

 Storyboard storyBoard = new Storyboard();
 storyBoard.Children.Add(slideDown);
 storyBoard.Children.Add(slideLeft);
 Storyboard.SetTargetName(slideDown, myCanvas.Name);
 Storyboard.SetTargetName(slideLeft, myCanvas.Name);
 Storyboard.SetTargetProperty(slideLeft, new PropertyPath(Canvas.LeftProperty));
 Storyboard.SetTargetProperty(slideDown, new PropertyPath(Canvas.TopProperty));

 myCanvas.BeginStoryboard(storyBoard);

答案 1 :(得分:0)

这是我用来修复我遇到的问题的代码......

public static void Friend(Canvas canvas)
{
    var random = new Random();
    foreach (var element in canvas.Children.OfType<Image>())
    {
        var elementName = Regex.Split(element.Name, "_");
        if (elementName[0] == "friend")
        {
            var slideDown = new DoubleAnimation
            {
                From = Canvas.GetBottom(element),
                To = Canvas.GetBottom(element) - element.Height,
                Duration = new Duration(TimeSpan.FromSeconds(1))
            };
            slideDown.Completed += (sender, e) =>
            {
                element.Source = Core.StreamImage(Wardrobe.Friends[Wardrobe.RandomFriend()]);
                Canvas.SetLeft(element, random.Next(0, (int)(canvas.ActualWidth - element.Width)));
                var slideUp = new DoubleAnimation
                {
                    From = Canvas.GetBottom(element),
                    To = Canvas.GetBottom(element) + element.Height,
                    Duration = new Duration(TimeSpan.FromSeconds(1))
                };
                element.BeginAnimation(Canvas.BottomProperty, slideUp);
            };
            element.BeginAnimation(Canvas.BottomProperty, slideDown);
        }
    }
}