C#在父窗口中調用子窗口的過程:
1、 創建子窗口對象
2、 顯示子窗口對象
筆者的程序中,主窗體MainFrm通過菜單調用子窗口ChildFrm。在窗體中定義了子窗口對象,然后在菜單項點擊事件中,加入了如下代碼來創建和顯示子窗口:







當點擊菜單中的OpenChild項時,創建了子窗口並顯示在最前面。此時如果關閉子窗口再點擊菜單打開,不會有問題。但是如果子窗口沒有關閉的情況下,再次點擊菜單中的OpenChild項,則會再創建一個子窗口。兩個子窗口具有相同的內容,這不是我們所希望看到的。
為此,對菜單項點擊事件做如下改進:















這樣修改的目的是:當子窗口對象存在時,直接顯示子窗口。當子窗口不存在時,創建子窗口,然后再顯示。
現在來檢驗效果:當第一次點擊OpenChild菜單項時,創建子窗口並正確顯示。不關閉子窗口的情況下再點擊OpenChild菜單項,子窗口只顯示了一個,說明按預期工作了。現在,我們關閉子窗口,再點擊OpenChild菜單項,程序在運行到下面這個語句時出現“未處理ObjectDisposedException”異常。
if(myChildFrm != null)
{
myChildFrm.Show();//顯示子窗口
錯誤信息:無法訪問已釋放的對象。對象名:“childFrm”。

這就讓人奇怪了。如果子窗口沒有被銷毀,那它就應該能夠正確顯示。點擊了關閉子窗口,顯然應該子窗口已經銷毀了,按理myChildFrm等於null,運行的時候應該直接運行else后面的語句塊,為什么卻進入了滿足myChildFrm!=null的語句塊呢?
其實,這個問題與C#的垃圾回收有關。垃圾回收器管理所有的托管對象,所有需要托管數據的.NET語言(包括C#)都受運行庫的垃圾回收器的制約。垃圾回收器可以確定運行垃圾回收的最佳時間,自動進行垃圾回收。然而垃圾回收的一個產物是:C#對象沒有確定性毀壞。所以會出現子窗口對象已被銷毀,但又不為null,故出現訪問時產生“未處理ObjectDisposedException”異常(來自於“從小處看C#.net垃圾回收”一文)。
如何解決這個題,有人提出:應該應該徹底回收Child所占的資源。並提供了解決方法(請搜索“從小處看C#.net垃圾回收”查看相關情況)。
其實,現在我們需要解決的問題僅僅是:子窗口已經被銷毀,但對象卻不為null。只需要對你窗口中的菜單點擊事件函數進行簡單修改就可以了。

















前面這是按邏輯的方式進行思考的,顯示子窗口和獲得焦點兩行是重復的,兩個if語句也可以做一下簡化。指定子窗口和父窗口的父子關系。最后的結果是這樣:








myChildFrm.Show(); //顯示子窗口
myChildFrm.Focus(); //子窗口獲得焦點
}


這樣,就能夠如我們如願般調用子窗口了。