我们的应用程序使用动画在消息窗口关闭时淡出。为此,我们重写OnClosing,如果我们还没有完成动画,我们取消关闭并启动动画。动画完成后,我们关闭窗口。这似乎是基于我在网上看到的相当普遍的模式,因为Closing and Closed不是可路由的事件。
问题是,我们偶尔会看到一个窗口“卡住” - 动画似乎没有发生,所以“完成”标志永远不会被设置,窗口就在那里,取消任何关闭事件。有时候,动画最终开始关闭,窗口关闭,但有时它似乎永远卡住了(虽然显然你无法确定......停止问题以及所有......)。
有没有人想过为什么即使在调用Begin()之后Storyboard也不会被踢掉?如果没有真正深入挖掘Storyboard代码/数据结构,感觉就像是在等待事情真正开始之前发生,从未发生过。
以下是我目前排除的一些可能性:
那就是说,这里有一些可能有所贡献的事情:
我怀疑最后一个最强烈,因为它是最近添加的,并且在此更改之前从未报告/注意到此行为(尽管我无法明确地说明从未在此更改之前发生) 。但是其他与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陷入了相同的状态。因此,一旦我们处于这种状态,行为几乎似乎从一个窗口“传递”。
编辑: 我已经排除了另一种可能性 - 我想知道第二个窗口的“淡入”故事板是否与第一个窗口的“淡出”故事板有些冲突,并以某种方式影响第二个窗口的淡出。但即使在删除淡入故事板后,问题仍然存在。 此外,如果我用一个半秒的调度计时器(即只是延迟关闭,没有动画)替换淡出故事板,问题就完全消失了。只是一个完整性检查它肯定与动画有关...
答案 0 :(得分:0)
_closingStoryBoard.Begin(this);
答案 1 :(得分:0)
我从来没有明确说明为什么会发生这种情况,但这似乎与我第二个窗口显示第二个窗口仍然是动画的事实有关。我仍然不明白为什么这会引起问题,但我能够通过等待第一个完全关闭然后显示第二个(基本上挂在第一个窗口的Closed事件上)来解决它。
如果“等待第一个窗口关闭”的解决方法永远不够用,我们仍然想知道为什么这样做会这样做......