WinForm与WPF .Close()事件

问题描述 投票:2回答:2

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中的一个实例

WPF,相同的代码:

  1. 'this.close()'不会抛出异常
  2. 如果Form1关闭,Form2将作为MainWindow保持打开状态。

Why is the Difference?

(编辑)我知道在Winform中我不能在构造函数中关闭相同的形式,因为它尚未创建,但是how is WPF differ with it in constructor call?

如果我希望所有儿童窗户关闭,如果父母关闭,WinForm方式怎么办?

c# wpf winforms
2个回答
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
投票

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.