WinForm与WPF .Close()事件

时间:2014-01-19 08:37:31

标签: c# wpf winforms

WinForm

public Form1()
{
    Form2 obj = new Form2();
    obj.show(); //shows form2
    this.Close(); //exception crash: because constructor has not yet called `new Form1.show()`
}

Winform

  1. 'this.close()'将通过异常并崩溃(无法处置未初始化的对象)
  2. 如果我没有在Form1中调用.close,并且我关闭(X)Form1,Form2也会因为它是Form1中的实例而被关闭
  3. <{1>}中的

    ,相同的代码:

    1. 'this.close()'不会通过例外
    2. 如果Form1已关闭,Form2将保持打开状态为MainWindow。
    3. WPF

      (编辑)我知道在Winform中我无法在构造函数中关闭相同的表单,因为它尚未创建,但是Why is the Difference?

      如果我希望所有子窗口关闭,如果父级关闭,how is WPF differ with it in constructor call?方式怎么办?

2 个答案:

答案 0 :(得分:4)

区别在于如何实现每个类的Close方法。尽管它们在功能和外观上有相似之处,但System.Windows.Forms.Form和System.Windows.Window是围绕两种不同架构构建的两个完全不同的类。

System.Windows.Forms.Form自.NET 1.0以来一直存在,并且主要是围绕本机前端(即非面向对象的)Windows UI库的简单易用的包装器。

System.Windows.Window是WPF中的一部分,它是在.NET 3.0中引入的,它试图在CLI之上构建一个现代的UI框架(而不是简单地包装旧的Windows UI库)。因此,System.Windows.Window的实现可能与System.Windows.Forms.Form完全不同。此外,虽然这些类上可用的操作可能表面上相似,但它们在语义上可能不相同。从这个意义上说,Form.Close和Window.Close不一定具有完全相同的含义。

现在,在这种特殊情况下,根据文档(http://msdn.microsoft.com/en-us/library/system.windows.forms.form.close(v=vs.110).aspx),您将收到此异常,因为“在创建句柄时窗体已关闭”。如果你稍微解压缩这个语句,那意味着你在创建表单的窗口句柄(HWND)之前调用了Close方法。这实际上与您在构造函数中关闭窗口这一事实无关:此时Form类的构造函数已经完成。 .NET中的Form对象表示Windows操作系统中的本机窗口,由窗口句柄(或HWND,即C / C ++中使用的类型名称)标识。但是,因为创建窗口句柄是一个昂贵的过程,所以Form对象实际上不会创建句柄,直到它实际需要它。因此,在调用Form.Show,Form.HWND或其他强制创建它的方法之前,窗体对象的窗口句柄不存在。如果你在this.Close()之前调用this.Show(),则不会抛出任何异常。

为什么System.Windows.Window不是这种情况?我的猜测是System.Windows.Window中的Close方法有点“更聪明”,如果它还不存在,只需跳过处理句柄的步骤。或者,也许窗口句柄是急切创建的,与Forms实现不同。

这种差异是否完全是故意的很难说。现在还不完全清楚“关闭”一个从未在第一时间显示的窗口是否合理,以及尝试这样做是否应该导致异常。它是一个设计选择。微软程序员现在可能更喜欢System.Windows.Window.Close的语义,而不是宽容的System.Windows.Forms.Close,但进行这样的更改不会向后兼容。或者,可能没有人真正注意到或者想到差异很大。

答案 1 :(得分:1)

在WPF中,您不会手动处理WPF对象,当没有对它们的引用时,它们会被垃圾收集。

由于你的Form1引用了Form2,你的Form1将保留在.close()隐藏表单的背景中,直到你关闭Form2。

您可以在Form1的关闭事件中销毁所有对象,或者您可以强制应用程序关闭,这不是一个好主意,除非您处理未保存的数据。

这是关于这样做的信息How to exit a WPF app programmatically?