C#中通過父視窗調用子視窗的問題

來源:互聯網
上載者:User
  C# 在父視窗中調用子視窗的過程: 1、  建立子視窗對象 2、  顯示子視窗對象   筆者的程式中,主表單MainFrm通過菜單調用子視窗ChildFrm。在表單中定義了子視窗對象,然後在功能表項目點擊事件中,加入了如下代碼來建立和顯示子視窗: Private childFrm myChildFrm  =   null ;  // 定義子視窗對象
private   void  OpenChildFrmToolStripMenuItem_Click( object  sender, EventArgs e)
... {
        myChildFrm = new ChildFrm();//建立子視窗對象
        myChildFrm.Show();//顯示子視窗
        myChildFrm.Focus();//使子視窗獲得焦點
} 當點擊菜單中的OpenChild項時,建立了子視窗並顯示在最前面。此時如果關閉子視窗再點擊菜單開啟,不會有問題。但是如果子視窗沒有關閉的情況下,再次點擊菜單中的OpenChild項,則會再建立一個子視窗。兩個子視窗具有相同的內容,這不是我們所希望看到的。 為此,對功能表項目點擊事件做如下改進: private   void  OpenChildFrmToolStripMenuItem_Click( object  sender, EventArgs e)
... {
    if(myChildFrm != null)
    ...{
        myChildFrm.Show();//顯示子視窗
        myChildFrm.Focus();//使子視窗獲得焦點
    }
    else
    ...{
        myChildFrm = new ChildFrm();//建立子視窗對象
        myChildFrm.Show();//顯示子視窗
        myChildFrm.Focus();//使子視窗獲得焦點
    }
}
這樣修改的目的是:當子視窗對象存在時,直接顯示子視窗。當子視窗不存在時,建立子視窗,然後再顯示。 現在來檢驗效果:當第一次點擊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。只需要對你視窗中的菜單點擊事件函數進行簡單修改就可以了。 private   void  OpenChildFrmToolStripMenuItem_Click( object  sender, EventArgs e)
... {
    if(myChildFrm != null)
    ...{
          if(myChildFrm.IsDisposed)
                  myChildFrm = new ChildFrm();//如果已經銷毀,則重新建立子視窗對象
          myChildFrm.Show();
          myChildFrm.Focus();
     }
    else
    ...{
        myChildFrm = new ChildFrm();
        myChildFrm.Show();
        myChildFrm.Focus();
    }
}
前面這是按邏輯的方式進行思考的,顯示子視窗和獲得焦點兩行是重複的,兩個if語句也可以做一下簡化。指定子視窗和父視窗的父子關係。最後的結果是這樣: private   void  OpenChildFrmToolStripMenuItem_Click( object  sender, EventArgs e)
... {
    if(myChildFrm == null || myChildFrm.IsDisposed)
    ...{  
        myChildFrm = new ChildFrm();
    }
    myChild..MdiParent = this; //建立父子關係
        myChildFrm.Show(); //顯示子視窗
    myChildFrm.Focus();  //子視窗獲得焦點
} 這樣,就能夠如我們如願般調用子視窗了。 附  
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.