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
.close
,并且我关闭(X)Form1,Form2也会因为它是Form1中的实例而被关闭,相同的代码:
WPF
(编辑)我知道在Winform中我无法在构造函数中关闭相同的表单,因为它尚未创建,但是Why is the Difference?
。
如果我希望所有子窗口关闭,如果父级关闭,how is WPF differ with it in constructor call?
方式怎么办?
答案 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?