情节提要.Begin()偶尔会被阻止或延迟

本文关键字:延迟 偶尔 Begin | 更新日期: 2023-09-27 18:22:00

我们的应用程序使用动画在消息窗口关闭时淡出消息窗口。要执行此操作,我们将覆盖"打开关闭",如果尚未完成动画,则取消关闭并开始动画。动画完成后,我们关闭窗口。根据我在网上看到的情况,这似乎是一种相当常见的模式,因为关闭和关闭都不是可路由的事件。

问题是,我们偶尔会看到一个窗口被"卡住"——动画似乎没有发生,所以"完成"标志永远不会被设置,窗口只是坐在那里,取消了任何关闭的事件。有时,动画最终开始,窗口关闭,但有时它似乎被永久卡住了(尽管很明显你不能确定……停止的问题等等…)

有人想过为什么即使调用了Begin(),Storyboard也不会被启动吗?如果没有能够真正深入地挖掘故事板代码/数据结构,感觉就像是在等待某件事发生,然后才真正开始,而这从未发生过。

以下是我目前已经排除的一些可能性:

  • 错误的线程(所有窗口、动画、故事板等都是在GUI线程上创建/处理/访问的)
  • GUI线程被阻止(单击X仍然会触发关闭事件,GUI线程会响应其他窗口、系统托盘等中的事件)
  • GUI线程繁忙(我们只在GUI线程上进行UI工作,通常一次只打开一个窗口,最多运行一个"关闭"动画)

也就是说,以下是一些可能起作用的因素:

  • Windows可以相互关闭(在某些情况下,如果其中一个已经打开,则新窗口将关闭现有窗口)
  • 我们还有一个通过XAML绑定到Loaded事件的"淡入"动画,但这似乎是正确完成的
  • 我们最近删除了"主"UI窗口,因此应用程序的主窗口现在是一个伪隐藏窗口

我最强烈地怀疑最后一个,因为它是最近添加的,而且在更改之前从未报告/注意到这种行为(尽管我不能肯定地说,在更改之前,它从未发生过)。但其他与GUI/窗口相关的事件仍然可以工作,淡出动画逻辑在大多数情况下都可以工作。

最后,这里是我们制作闭幕动画的代码:

public class MyWindow : Window {
    private bool _storyBoardCompleted;
    private Storyboard _closingStoryBoard;
    protected Storyboard GetClosingStoryBoard()
    {
        Grid mainGrid = (Grid)FindName("MainGrid");
        DoubleAnimation closingAnimation = new DoubleAnimation();
        closingAnimation.From = 1;
        closingAnimation.To = 0;
        closingAnimation.Duration = new Duration(TimeSpan.FromMilliseconds(500));
        Storyboard.SetTarget(closingAnimation, mainGrid);
        Storyboard.SetTargetProperty(closingAnimation, new PropertyPath(OpacityProperty));
        Storyboard storyboard = new Storyboard();
        storyboard.Children.Add(closingAnimation);
        storyboard.Completed += StoryboardCompleted;
        return storyboard;
    }
    private void StoryboardCompleted(object sender, EventArgs e)
    {
        _storyBoardCompleted = true;
        Close();
    }
    protected override void OnClosing(CancelEventArgs e)
    {
        if (_closingStoryBoard == null)
        {
            _closingStoryBoard = GetClosingStoryBoard();
            _closingStoryBoard.Begin();
        }
        if (!_storyBoardCompleted)
        {
            e.Cancel = true;
        }
    }
}

编辑:每当我们及时打开其中两个非常靠近的窗口,并在显示第二个窗口之前关闭第一个窗口时,这个问题似乎就会弹出。本质上:

window1.Show()
window1.Close()
window2.Show()

在这一点上,如果我们试图关闭window2,它会像上面的代码中那样取消关闭,但动画不会开始(因此出现了问题)。如果我们稍后调用window2.Close(),紧接着调用window3.Show()(即显示第三个窗口),那么window2的动画将结束,窗口将关闭,但window3仍处于相同状态。因此,一旦我们处于这种状态,这种行为似乎就会从一个窗口"传递"到另一个窗口。

编辑:我已经排除了另一种可能性——我想知道第二个窗口的"淡入"情节提要是否与第一个窗口的《淡出》情节提要发生了某种冲突,并以某种方式影响了第二个窗的淡出。但即使在删除了淡入情节提要后,问题也会出现。此外,如果我用半秒的调度计时器(即,只有延迟关闭,没有动画)替换淡出情节板,问题就会完全消失。只是一个理智的检查,它肯定与动画有关。。。

情节提要.Begin()偶尔会被阻止或延迟

您是否尝试过向Begin方法添加参数:

_closingStoryBoard.Begin(this);

我从来都不太清楚为什么会发生这种情况,但这似乎与我显示第二个窗口而第一个窗口仍在动画有关。我仍然不明白为什么会出现问题,但我可以通过等待第一个窗口完全关闭,然后再显示第二个窗口来解决问题(基本上是挂接到第一个窗口的Closed事件)。

我仍然很想知道为什么会这样,以防"等待第一个窗口关闭"的变通方法不再足够。。。