2008-12-19 1984 views
44

我正在处理一个应用程序,该应用程序显示一些可以由用户关闭或自动关闭的子窗口。在调试一些正在抛出的异常时,我发现我正试图在已经关闭的窗口上调用Hide()等方法;这个特殊的代码分支对两种情况都是常见的,我没有注意到这一点。如何判断WPF窗口是否关闭?

我的第一个想法之一是寻找一个Window上的财产,这表明窗户已关闭。我似乎无法找到一个。在WinForms中,我希望IsDisposed属性有一个可靠的指标,表单已被关闭(它不会可靠地用于对话框,但我不用对话框工作)。我没有看到任何东西相当于WindowWindow.Close()的文档似乎并未指出由该方法更改的任何属性。我是否错过了一些显而易见的东西,或者是唯一知道窗口是否已关闭以处理事件的方法?对于简单的任务来说,这似乎是一种苛刻的要求。

回答

45

根据MSDN WPF论坛上的this conversation(请参阅最后一篇文章),您可以检查IsLoaded是否为false,这意味着该窗口“适合”卸载其内容。我希望这对你有用!

+4

该属性不能从另一个线程访问,并调用一个调用安置在窗口块无限。所以我最终使用了我自己的实例变量,并以不需要同步的方式访问它(在OnClosed方法的开始处isClosed = true,然后再次阅读它)。 – ygoe 2012-02-22 09:17:24

+3

如果事件仍在处理中,这不起作用。例如,如果按钮单击处理程序关闭一个窗口,然后打开另一个窗口,并且第二个窗口的初始化检查第一个“IsLoaded”,它将返回“true”。 – nmclean 2014-02-26 16:16:29

7

另一种方式:Application.Windows包含打开的窗口列表。 你可以检查这个集合是否包含你的窗口(它在关闭后被删除)。

看起来你必须致电OfType<Window>(),因为它是一个专门的集合。

+3

要小心这个 - 这可能有时包含没有关闭的窗口,尤其是那些由于XAML – 2012-03-30 21:50:38

3

希望这可帮助您:

PresentationSource.FromVisual(window)== null;

3

我不知道为什么IsDisposed性质是内部的,但如果你不害怕反思:

var window = new Window(); 
var propertyInfo = typeof(Window).GetProperty("IsDisposed", BindingFlags.NonPublic | BindingFlags.Instance); 
var isDisposed = (bool)propertyInfo.GetValue(window); 

话虽这么说,反思是不是被过度使用,因为你不再受该类的公共API保护。如果你走这条路线,一定要至少使用单元测试。

4

我的解决办法是简单的事件附加到对话框的Closed事件:

MikesDialog dlg = new MikesDialog(); 
dlg.Closed += delegate 
{ 
    // The user has closed our dialog. 
    validationgDlg = null; 
}; 

// ...elsewhere in the code... 

if (validationgDlg != null) 
{ 
    // Our "MikesDialog" is still open... 
    . . . 
} 
4

如果你从Window类派生的,你可以这样做:

public bool IsClosed { get; private set; } 

protected override void OnClosed(EventArgs e) 
{ 
    base.OnClosed(e); 
    IsClosed = true; 
} 

它在有优势注册Closed事件 - 无需取消注册回调。

0

您可以在非静态的属性添加到WindowClass bool IsClosed,并在Closed事件设置为true:

public partial class MyWindow : Window 
{ 
    public bool IsClosed { get; set; } = false; 
    public MyWindow() 
    { 
     Closed += MyWindow_Closed; 
     InitializeComponent(); 
    } 
}  

private void MyWindow_Closed(object sender, EventArgs e) 
{ 
    IsClosed = true; 
}