WPF故事板已完成事件

时间:2018-04-05 19:36:05

标签: c# .net wpf

我遇到的问题是我无法在Completed事件中向Storyboard发出Stop()命令。

例如

private void ShowStandbyGrid()
{
    StandbyGrid.Visibility = Visibility.Visible;
    Storyboard sbFadeIn = this.FindResource("StandbyGridFadeIn") as Storyboard;

    sbFadeIn.Completed += (s, a) =>
    {
        Console.WriteLine("Completed Event Fired");
        sbFadeIn.Stop(this);    //<-- This does not cause the storyboard animation to stop
    };


    sbFadeIn.Begin(this, true);
}

我可以看到事件正在触发,但似乎并不想停止故事板动画。

由于这个问题,每当对UI做一些事情时,这个动画将连续运行。我相信这是因为动画永远不会停止。

我错过了什么吗?

更新1

这是故事板的xaml

    <Storyboard x:Key="StandbyGridFadeIn">
        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="StandbyGrid">
            <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
            <EasingDoubleKeyFrame KeyTime="0:0:1" Value="1"/>
        </DoubleAnimationUsingKeyFrames>
    </Storyboard>

更新2 好的,经过8个多小时的测试和尝试,我仍然不知道为什么它不起作用。但是,这里有几个事实(或问题/发现)

  1. 我创建了一个按钮以反向运行故事板。故事板按预期执行(StandbyGridFadeIn的反转,更像是FadeOut)。但是,执行后,StandByGridFadeIn会在没有任何函数调用的情况下自动执行。完成后,我看到控制台输出2 x“已完成事件已触发”。

  2. 我输出GetCurrentState(this);在sbFadeIn.Stop之前(这个);输出显示“填充”。然后我输出GetCurrentState(this);在sbFadeIn.Stop(this);之后,输出仍显示“Filling”。

  3. 我做了另一个测试,我把sbFadeInStop(这个); sbFadeIn.Begin之后立即(这是真的);动画停止成功。

  4. 我想特别讨论观察#2,认为当且仅当动画完成时才触发事件,第一个GetcurrentState(this)应该已经输出“Stopped”。这是对的吗?

1 个答案:

答案 0 :(得分:-2)

从代码判断 https://stackoverflow.com/a/5645796/903783

您可能需要使用

Dispatcher.Invoke(DispatcherPriority.Normal, 
                  (Action)delegate() { sbFadeIn.Stop(); });

在最近的C#中你可能只能写

Dispatcher.Invoke(DispatcherPriority.Normal, 
                  ()=> sbFadeIn.Stop() );

然而,正如其他人在下面评论过的那样,因为你应该已经在UI线程上执行,所以不太可能出现问题

<强>更新

上面的Clemens评论也是一个可能的尝试路径,也就是说你可能需要将FillBehavior改为Stop而不是默认的HoldEnd

https://msdn.microsoft.com/en-us/library/system.windows.media.animation.timeline.fillbehavior(v=vs.110).aspx

替代方法是删除StoryBoard(例如MyStoryboard.Remove(MyControl)),如下所示:

https://docs.microsoft.com/en-us/dotnet/framework/wpf/graphics-multimedia/how-to-set-a-property-after-animating-it-with-a-storyboard

那里有一个示例甚至展示了如何使用BeginAnimation从特定属性中删除动画并传递null第二个参数