【问题标题】:How do you tell if a WPF Window is closed?如何判断 WPF 窗口是否关闭?
【发布时间】:2010-09-27 18:34:30
【问题描述】:

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

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

【问题讨论】:

    标签: wpf


    【解决方案1】:

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

    【讨论】:

    • 这个属性不能从另一个线程访问,并且无限调用对已处理的Window块的调用。所以我最终为此使用了我自己的实例变量并以不需要同步的方式访问它(在 OnClosed 方法的开头 isClosed = true,然后稍后再读)。
    • 如果事件仍在处理中,这将不起作用。例如,如果一个按钮 Click 处理程序关闭一个窗口,然后打开另一个窗口,并且第二个窗口的初始化检查第一个窗口的 IsLoaded,它将返回 true
    • @nmclean 同意,我遇到过这样的情况,其中 WindowInteropHelper.EnsureHandle() 抛出异常,表明窗口已关闭,但 window.IsLoaded = true。
    【解决方案2】:

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

    public bool IsClosed { get; private set; }
    
    protected override void OnClosed(EventArgs e)
    {
        base.OnClosed(e);
        IsClosed = true;
    }
    

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

    【讨论】:

      【解决方案3】:

      希望这对你有用:

      PresentationSource.FromVisual(window) == null;

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 小心这个 - 这有时可能包含未关闭的窗口,特别是由于 XAML 错误而在初始显示期间失败的窗口
        【解决方案5】:

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

        【讨论】:

          【解决方案6】:

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

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

          话虽如此,反射不应被过度使用,因为您不再受到该类的公共 API 的保护。如果你走这条路,请务必至少使用单元测试。

          【讨论】:

            【解决方案7】:

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

            【讨论】:

              【解决方案8】:

              在某些情况下检查Application.Current.MainWindow.IsActive 就足够了

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2011-03-17
                • 2010-10-05
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多