【问题标题】:What is the correct way to dispose of a WPF window?处理 WPF 窗口的正确方法是什么?
【发布时间】:2010-10-08 18:41:29
【问题描述】:

我有一个 WPF 窗口,我通过调用 Show() 从另一个窗口创建它,然后让它 Close() 本身。当窗口关闭时,我预计它会死掉,调用它的析构函数,并删除它的所有子元素(例如计时器..)。

调用此类操作的正确方法是什么?

【问题讨论】:

    标签: wpf window


    【解决方案1】:

    关于Window持有的资源,根据documentation

    (强调)

    关闭窗口会引发 Closing 事件。如果收盘 事件未取消,会发生以下情况:

    1. 从 Application.Windows 中删除窗口(如果应用程序 对象存在)。

    2. 如果所有者/拥有者,则从所有者窗口中删除窗口 在显示拥有的窗口之前建立关系并且 所有者窗口打开后。

    3. 引发了 Closed 事件。

    4. 由 Window 创建的非托管资源被释放。

    5. 如果调用 ShowDialog 来显示窗口,则 ShowDialog 返回。

    我相信这是按顺序列出的。


    我不确定计时器子问题的具体情况;我认为这个问题没有足够的细节来真正回答这个问题。

    【讨论】:

      【解决方案2】:

      以防万一,我会加两分钱。

      我的问题是我没有进行足够的故障排除。我的窗口是一个可以打开、关闭和重新打开的子窗口,所以我添加了以下内容以防止它完全关闭:

      private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
        e.Cancel = true;
        this.Hide();
      }
      

      但是,当 Window.Close 被调用时,它只是隐藏了窗口。我最终理解并添加了以下内容:

      private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) {
        e.Cancel = true;
        this.Hide();
      }
      
      public void Close() {
        this.Closing -= Window_Closing;
        //Add closing logic here.
        base.Close();
      }
      

      这很好 - 它删除了阻止窗口关闭的事件处理程序,然后将其关闭。

      【讨论】:

      • 哈,我在尝试关闭子窗口时遇到了完全相同的错误(忘记取消订阅阻止关闭的事件处理程序)。拯救了我的一天:)
      • 这个解决方案是有问题的,因为它隐藏了原来的Window.Close 方法。最好有一个单独的方法来做同样的事情。
      • @IanKemp 我不主张将其用作通用解决方案,但在这种情况下隐藏Window.Close 完全是故意的,因为调用隐藏方法会导致意外和不正确的行为。
      【解决方案3】:

      Close() 释放所有非托管资源,并关闭所有拥有的Windows。

      您需要确定性处置的任何其他托管资源都应通过Closed 事件进行处理。

      Reference

      (注意:删除了之前的答案,完全是错误的猜测)

      【讨论】:

        【解决方案4】:

        关闭窗口并确信您已向其释放所有资源及其任何子级将导致逻辑​​树中所有表现良好的元素被垃圾回收。

        我说“表现良好”是因为理论上可以有一个元素执行诸如创建一个未正确停止的线程之类的操作,但实际上,如果您使用的是基本的 WPF 框架和编写良好的控件,您应该放开一切就好了。

        【讨论】:

          【解决方案5】:

          与 Windows 窗体不同,实际上需要显式释放的 WPF 元素很少。

          对于 Window,调用 Close() 足以根据 documentation 处理所有托管和非托管资源。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-07-15
            • 2015-02-11
            • 2014-09-23
            • 2013-07-24
            • 2011-12-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多