事件未在故事板中正确触发

时间:2013-02-22 17:58:29

标签: c# wpf xaml events animation

我有一个自定义UserControl需要在X上从1缩放到0,然后使用以下编码Storyboard从0回到1:

Storyboard storyboard = new Storyboard();

DoubleAnimation animationFlipBegin = new DoubleAnimation();
animationFlipBegin.BeginTime = TimeSpan.FromSeconds(0.4D);
animationFlipBegin.Duration = TimeSpan.FromSeconds(0.1D);
animationFlipBegin.To = 0D;
animationFlipBegin.SetValue(Storyboard.TargetProperty, myUserControl);
animationFlipBegin.SetValue(Storyboard.TargetPropertyProperty, BuildPropertyPath("(FrameworkElement.RenderTransform).(TransformGroup.Children)[1].(ScaleTransform.ScaleX)"));

DoubleAnimation animationFlipEnd = new DoubleAnimation();
animationFlipEnd.BeginTime = TimeSpan.FromSeconds(0.5D);
animationFlipEnd.Duration = TimeSpan.FromSeconds(0.1D);
animationFlipEnd.To = 1D;
animationFlipEnd.SetValue(Storyboard.TargetProperty, myUserControl);
animationFlipEnd.SetValue(Storyboard.TargetPropertyProperty, BuildPropertyPath("(FrameworkElement.RenderTransform).(TransformGroup.Children)[1].(ScaleTransform.ScaleX)"));

storyboard.Children.Add(animationFlipBegin);
storyboard.Children.Add(animationFlipEnd);
storyboard.Begin();

当ScaleX值达到0时,必须在UserControl上调用一个函数。所以我的第一次尝试是添加以下代码:

animationFlipBegin.Completed = new EventHandler(DoAction);

private void DoAction(Object sender, EventArgs e)
{
    myUserControl.DoAction();
}

问题是DoAction仅在Storyboard完成后被调用,而不是在DoubleAnimation完成时被调用,可能是由于线程...这对我来说绝对不利!

所以...我的第二次尝试是修改我的自定义UserControl代码,如下所示:

<UserControl.RenderTransform>
    <TransformGroup>
        <ScaleTransform Core:Name="Scaling" Changed="OnScaleChanged"/>

private void OnScaleChanged(Object sender, EventArgs e)
{
    if (Scale.ScaleX == 0D)
        DoAction();
}

最初看起来像一个聪明的主意,但事实并非如此。 ScaleTransform.Changed有时只被调用,当ScaleX为0时,它从未被调用,从我看到的调试代码开始。

所以...我仍然可以解决的唯一解决方案是将我的Storyboard拆分为两个单独的Storyboard,然后在第一个事件完成后调用DoAction事件。看到它太丑了,我真的想找到另一种方式。有什么建议吗?

1 个答案:

答案 0 :(得分:0)

如果在没有故事板的情况下单独运行动画怎么办?只需在第一个动画的Completed处理程序中启动第二个动画,而不是BeginTime

var animationFlipBegin = new DoubleAnimation
{
    BeginTime = TimeSpan.FromSeconds(0.4),
    Duration = TimeSpan.FromSeconds(0.1),
    To = 0
};

var animationFlipEnd = new DoubleAnimation
{
    Duration = TimeSpan.FromSeconds(0.1),
    To = 1
};

var scaleTransform = (ScaleTransform)((TransformGroup)RenderTransform).Children[1];

animationFlipBegin.Completed +=
    (o, e) =>
    {
        DoAction();
        scaleTransform.BeginAnimation(ScaleTransform.ScaleXProperty, animationFlipEnd);
    };

scaleTransform.BeginAnimation(ScaleTransform.ScaleXProperty, animationFlipBegin);