开发者社区> 阿笨net> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

C# 子窗体中调用父窗体中的方法(或多窗体之间方法调用)

简介: 本文转载:http://www.csframework.com/archive/2/arc-2-20110805-1771.htm 文章侧重点主要是讨论“窗体”与“窗体”之间方法的调用,以及“MDI父窗体”与“Chilid子窗体”之间如何相互的调用方法。
+关注继续查看

本文转载: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.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模块。

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
JDK8新特性之方法引用
什么是方法引用 方法引用是只需要使用方法的名字,而具体调用交给函数式接口,需要和Lambda表达式配合使用。 如:
37 0
多天线传输方案的选择 | 带你读《大规模天线波束赋形 技术原理与设计 》之六
CSI 的获取能力对于 MIMO 技术方案的 选择有着至关重要的影响。例如,同样是为了保证传输的可靠性,发射分集技术将同一信息的多个冗余样本通过不同的数据通道进行发送,而单流传输的波束赋形技术则是将全部的发射功率和信息馈送到理想的数据通道之中。其中的一个重要差别便是,发射机一侧能否获得及时准确的信道 状态信息。
3179 0
5G的要求和主要性能指标 | 《5G移动无线通信技术》之六
这里对前面章节所述用例的要求加以总结,表达了5G主要性能指标(KPI)。
5055 0
用 css 做web图形化处理
图片来自 CHRIS COYIER 在前端开发中,你或多或少都会接触到css图形。之前我整理过 伪元素&伪类 的内容,为的就是更加熟悉了解它们,以便更好的使用它们。
1092 0
在WPF中使用字体图标
原文:在WPF中使用字体图标 一、源码描述    这是一款基于WPF窗体应用程序的字体图标示例源码,    该源码简单易懂使用于初学者和实战项目应用,    感兴趣的朋友们可以下载看看哦。二、功能介绍    1、用ICO字体代替纯文字    三、实现步骤    1、在网上下载Font ICO 字体字...
1113 0
jquery success 不执行
第一点:json 格式不对,少双引用之类 第二点:js文件没有引用(注:js可以用不是jquery可以用,有的时候以为js可以用那是默认的js函数,如果跳转可能js只要用相对路径就可以了)
546 0
托盘图标(NotifyIcon)详解
Windows xp下的托盘功能实现起来很简单,但如果要做一些高级一点的实现效果,以及良好的UI友好操作,那就需要下一小番功夫了。这里没有采用自己创建Tip窗口的方式,而是使用windows自带的Shell_NotifyIcon来完成一些还算Ok的效果。
1147 0
+关注
842
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
低代码开发师(初级)实战教程
立即下载
阿里巴巴DevOps 最佳实践手册
立即下载
冬季实战营第三期:MySQL数据库进阶实战
立即下载