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/ 老咸出品

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM