C# 子窗體中調用父窗體中的方法(或多窗體之間方法調用)


本文轉載:http://www.csframework.com/archive/2/arc-2-20110805-1771.htm

文章側重點主要是討論“窗體”與“窗體”之間方法的調用,以及“MDI父窗體”與“Chilid子窗體”之間如何相互的調用方法。

C# 子窗體中調用父窗體中的方法(或多窗體之間方法調用)


看似一個簡單的功能需求,其實很多初學者處理不好的,很多朋友會這么寫:

C# Code:

//父窗體是是frmParent,子窗體是frmChildA
//在父窗體中打開子窗體
frmChildA child =
new frmChildA();
child.MdiParent =
this;
child.Show();



//子窗體調父窗體方法:
//錯誤的調用!!!!!!!!
(this.MdiParent as frmParent).ParentFoo();

//來源:C/S框架網(www.csframework.com) QQ:1980854898



知道錯在那里嗎?錯在強依賴!如果父窗體與子窗體在同一個模塊內看似沒有錯,因為這種反向引用在同一個模塊內是可行的,但程序不能這么寫,你把它寫死了!固化了!假設我們的項目不斷在擴展,需要將父窗體與子窗體分開在不同的模塊,這段代碼就完了!因為父窗體模塊必須引用子窗體模塊,而子窗體需要用到frmParent的類,又要引用父窗體的模塊!這時構成了雙向引用,編譯不能通過,所以講程序寫死了!

有什么辦法解除這種依賴關系呢?辦法是有的,就是使用接口解除依賴關系!

我們把程序改下:


C# Code:

///<summary>
/// 主窗體接口
///</summary>
public interface IMdiParent
{
   void ParentFoo();
}


///<summary>
/// 子窗體接口
///</summary>
public interface IMyChildForm
{
   void Foo();
}



主窗體的代碼:


C# Code:

///<summary>
/// 主窗體,實現IMdiParent接口
///</summary>
public partial class frmParent : Form, IMdiParent
{
   public frmParent()
   {
      InitializeComponent();
   }
  
   private void form1ToolStripMenuItem_Click( object sender, EventArgs e)
   {
      //打開子窗體
      frmChildA child = new frmChildA();
      child.MdiParent = this;
      child.Show();
   }
  
   private void menuCallFoo_Click( object sender, EventArgs e)
   {
      //調用子窗體的Foo()方法
      Form activedChild = this.ActiveMdiChild;
      if ((activedChild != null) && (activedChild is IMyChildForm))
         (activedChild as IMyChildForm).Foo();
   }
  
   #region IMdiParent 成員
  
   public void ParentFoo()
   {
      MessageBox.Show("調用" this.GetType().FullName ".ParentFoo()方法!");
   }
  
   #endregion
}

//來源:C/S框架網(www.csframework.com) QQ:1980854898



子窗體的代碼:


C# Code:

///<summary>
/// 子窗體,實現IMyChildForm接口
///</summary>
public partial class frmChildA : Form, IMyChildForm
{
   public frmChildA()
   {
      InitializeComponent();
   }
  
   #region IMyChildForm 成員
  
   public void Foo()
   {
      MessageBox.Show("調用" this.GetType().FullName ".Foo()方法!");
   }
  
   #endregion
  
   private void btnParentFoo_Click( object sender, EventArgs e)
   {
      //調用父窗體的ParentFoo()方法
      if (( this.MdiParent != null) && ( this.MdiParent is IMdiParent))
      ( this.MdiParent as IMdiParent).ParentFoo();
   }
  
   private void btnErrCall_Click( object sender, EventArgs e)
   {
      //錯誤的調用
      ( this.MdiParent as frmParent).ParentFoo();
   }
  
   //來源:C/S框架網(www.csframework.com) QQ:1980854898
  




貼圖圖片


實現思路:

frmParent窗體所在的模塊依賴frmChildA所在模塊,而frmChildA只依賴IMdiParent接口,這正是《敏捷軟件開發》中所講的依賴倒置原則。最后,我們把IMdiParent接口部署在一個Common模塊內,實際上frmParent與frmChildA只需要依賴Common模塊。


免責聲明!

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



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