C# Close 与 Closing 、OnClosing与Closed详解

有许多软件可以设置“关闭主面板时,最小化到系统托盘,不退出程序”。是通过重载程序自身的OnClosing来完成的。那么OnClosing是什么呢?

度娘了一下,发现涉及到的问题不仅仅是Closing本身。还有Close、Closed、Closing。。。。下面贴出来共享下知识:

首先是Form.Close,Close是一个方法,窗体可调用这个方法让自身关闭。

然后是OnClosing,我们可以通过重载OnClosing来实现窗体关闭前的某种处理。比如,通过重载OnClosing让窗体最小化。代码:

1 protected override void OnClosing(CanelEventArgs e)
2 {
3     e.Cancel = true;
4     this.WindowState = FormWindowState.Minimized;
5     Hide();
6 }

Form.Close方法大概是这样子的:

1 Form.Close()
2 {
3      OnClosing(this.e);
4       if(!e.Cancel)//默认为false,即这里是true
5       //关闭窗口
6 }

所以,没有经过Close函数就调用OnClosing函数是会照样关闭窗口的。因为你直接调用OnClosing方法根本就没调用Close()方法。

这样,当我们单击窗口右上角那个叉叉的时候,窗体首先调用Close方法,Close方法再调用OnClosing方法。而我们通过重载OnClosing方法,让程序不是退出,而是最小化到系统托盘区。

Form.Close引发OnClosing,OnClosing引发Closing和FormClosing.

但是在MSDN上声明,在 .NET Framework 版本 2.0 及其以后版本,Form.Closed与 Form.Closing 事件已过时,请改用 Form.FormCloseing 和 Form.FormClosed 事件。

说是这么说,但是如果直接调用Form.FormClosing来阻止窗口的关闭时,假设,你已经做好了系统托盘的右键菜单。如果你直接在右键菜单里关闭窗口,窗口是不会关闭的,而是先根据语句 this.WindowState = FormWindowState.Minimized; 让窗口先最小化。只有两次系统托盘右键菜单退出时,才可以退出。而直接重载OnClosing则不会发生这样的BUG.

然后是Form.FormClosing,语态是进行时。是在窗体关闭时,需要处理的事情,基本等同于前边的OnClosing方法。比如C#可以添加NotifyIcon控件,加入ICO图标。将窗体属性中的,ShowIntaskBar设置为false。

然后写窗体的Form.FormClosing事件。可以得到:

1 private void Form1_FormClosing(object sender, FormClosingEventArgs e)
2 {
3      e.Canel = true;//默认为FALSE,关闭窗体。true为不关闭。
4      this.WindowState = FormWindowState.Minimized;//窗体最小化。
5      Hide();  
6 }//此代码有上述的BUG。请采用直接重载OnClosing的方法。

以后每次窗体关闭时,都自动最小化。又因为设置了ShowInstaskBar就不会在任务栏显示。但因为有了NotifyIcon,所以在系统托盘里可以看到自己的程序。

msdn上是这样解释的:

1)、在窗体关闭时,Form.FormClosing 事件发生。 窗体关闭时,此事件会得到处理,从而释放与此窗体关联的所有资源。 如果取消此事件,则该窗体保持打开状态。 若要取消窗体的关闭操作,请将传递给事件处理程序的 FormClosingEventArgs 的 Cancel 属性设置为 true。在显示为无模式窗口的 Form 上调用 Close 方法时,不能调用 Show 方法使窗体可见,因为窗体的资源已被释放。 若要隐藏窗体然后又使其可见,请使用 Hide 方法。

2)、如果窗体是多文档界面 (MDI) 父窗体,则在引发 MDI 父窗体的 FormClosing 事件之前将引发所有 MDI 子窗体的 FormClosing 事件。 同样,在引发 MDI 父窗体的FormClosed 事件之前,将引发所有 MDI 子窗体的 FormClosed 事件。 取消 MDI 子窗体的 FormClosing 事件不能防止引发 MDI 父窗体的 FormClosing 事件。 但是,取消该事件会将作为参数传递给父窗体的 FormClosingEventArgs 类的 Cancel 属性设置成 true。 要强制关闭所有 MDI 父窗体和子窗体,请将 MDI 父窗体中的 Cancel 属性设置成 false。

说白了,Form.FormClosing与OnClosing 的存在就是为了让我们有手段去阻止窗口的关闭。

 最后是Form.Closed方法:

在用户或Application类的Close方法或Exit方法关闭窗体后,会发生FormClosed事件。可以使用此事件释放窗体的一些资源。还可以使用此事件保存输入窗体中的一些信息或者更新父窗体。可以进行对窗体设置的保存啊,文件的保存啊,保存资源啊等等。

 

转载请注明 博客园 :http://www.cnblogs.com/gu-zhan/ 老咸出品

 

posted @ 2014-12-13 16:19  Mertin.Chen  阅读(11883)  评论(0编辑  收藏  举报