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

轉自:http://www.csframework.com/archive/2/arc-2-20110805-1771.htm

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

C# Code:

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



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


知道錯在那裏嗎?錯在強依賴!如果父窗體與子窗體在同一個模塊內看似沒有錯,因爲這種反向引用在同一個模塊內是可行的,但程序不能這麼寫,你把它寫死了!固化了!假設我們的項目不斷在擴展,需要將父窗體與子窗體分開在不同的模塊,這段代碼就完了!因爲父窗體模塊必須引用子窗體模塊,而子窗體需要用到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.MdiParentis 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模塊。

點擊下載附件 點擊下載附件 (如下載失敗,請郵件通知我們寄回給您,或QQ:23404761留言.)


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章