如何判断 WPF 窗口是否已关闭?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/381973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 19:52:57  来源:igfitidea点击:

How do you tell if a WPF Window is closed?

wpf

提问by OwenP

I'm working on an application that displays some child windows which can either be closed by the user or are automatically closed. While debugging some exceptions that were being thrown, I discovered I was trying to call methods like Hide()on a window that had already been closed; this particular branch of code was common to both cases and I hadn't noticed this.

我正在开发一个显示一些子窗口的应用程序,这些窗口可以由用户关闭或自动关闭。在调试一些抛出的异常时,我发现我试图调用方法,就像Hide()在已经关闭的窗口上一样;这个特定的代码分支在两种情况下都很常见,我没有注意到这一点。

One of my first ideas was to look for a property on Windowthat would indicate the window had been closed. I can't seem to find one. In WinForms, I'd look to the IsDisposedproperty for a somewhat reliable indicator that the form had been closed (it won't reliably work for a dialog but I'm not working with dialogs.) I don't see anything equivalent on Window. The documentation for Window.Close()doesn't seem to indicate any properties that are changed by the method. Am I missing something obvious, or is the only method to know if a window's been closed to handle the Closedevent? That seems kind of a harsh requirement for a simple task.

我的第一个想法是寻找Window可以表明窗户已关闭的属性。我似乎找不到一个。在 WinForms 中,我会查看IsDisposed属性以获得某种可靠的指示,表明表单已关闭(它不能可靠地用于对话框,但我不使用对话框。)我没有看到任何等效的Window. 的文档Window.Close()似乎没有指出该方法更改的任何属性。我是否遗漏了一些明显的东西,或者是知道窗口是否已关闭以处理Closed事件的唯一方法?对于一项简单的任务来说,这似乎是一项苛刻的要求。

回答by scwagner

According to this conversationon the MSDN WPF forums (see the last post), you can check to see if the IsLoaded is false, which means that the window is "eligible" for unloading its content. I hope that works for you!

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

回答by Tom

If you derive from the Window class, you can do this:

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

public bool IsClosed { get; private set; }

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

It has an advantage over registering for the Closed event - no need to un-register the callback.

与注册 Closed 事件相比,它具有优势 - 无需取消注册回调。

回答by Simon_Weaver

Another way : Application.Windowscontains a list of open windows. You can check is this collection contains your window (it is removed after closing).

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

Looks like you have to call OfType<Window>()because it is a specialized collection.

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

回答by dexiang

Hope this is useful for you:

希望这对您有用:

PresentationSource.FromVisual(window) == null;

PresentationSource.FromVisual(window) == null;

回答by Adrian Rus

I don't know why the IsDisposedproperty is internal, but if you don't fear reflection:

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

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

That being said, reflection is not to be overused because you're no longer protected by the public API of the class. Be sure to use at least unit tests if you go that route.

话虽如此,反射不会被过度使用,因为您不再受到类的公共 API 的保护。如果你走那条路,一定要至少使用单元测试。

回答by Mike Gledhill

My solution was to simply attach an event to the dialog's Closedevent:

我的解决方案是简单地将事件附加到对话框的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...
     . . .
}

回答by Mayer Spitzer

You can add a non static property to the WindowClass bool IsClosed, and set true on the Closedevent:

您可以向 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;
}