C# 多窗体之间方法调用
看似一个简单的功能需求,其实很多初学者处理不好的,很多朋友会这么写:
//父窗体是是frmParent,子窗体是frmChildA
//在父窗体中打开子窗体
frmChildA child = new frmChildA();
child.MdiParent = this;
child.Show();
//子窗体调父窗体方法:
//错误的调用!!!!!!!!
(this.MdiParent as frmParent).ParentFoo();
知道错在那里吗?错在强依赖!如果父窗体与子窗体在同一个模块内看似没有错,因为这种反向引用在同一个模块内是可行的,但程序不能这么写,你把它写死了!固化了!假设我们的项目不断在扩展,需要将父窗体与子窗体分开在不同的模块,这段代码就完了!因为父窗体模块必须引用子窗体模块,而子窗体需要用到frmParent的类,又要引用父窗体的模块!这时构成了双向引用,编译不能通过,所以讲程序写死了!
有什么办法解除这种依赖关系呢?办法是有的,就是使用接口解除依赖关系!
我们把程序改下:
/// <summary>
/// 主窗体接口
/// </summary>
public interface IMdiParent
{
void ParentFoo();
}
/// <summary>
/// 子窗体接口
/// </summary>
public interface IMyChildForm
{
void Foo();
}
主窗体的代码:
/// <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
}
子窗体的代码:
/// <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();
}
实现思路:
frmParent窗体所在的模块依赖frmChildA所在模块,而frmChildA只依赖IMdiParent接口,这正是《敏捷软件开发》中所讲的依赖倒置原则。最后,我们把IMdiParent接口部署在一个Common模块内,实际上frmParent与frmChildA只需要依赖Common模块。
Source Code for VS2008:
C# 多窗体之间方法调用的更多相关文章
- 多窗体之间方法调用 z
C# Code: /// <summary> /// 主窗体接口 /// </summary> public interface IMdiParent{ void Pare ...
- ASP.NET同页面内【用户控件与父页面】以及【用户控件与用户控件】之间方法调用
在用户控件中,获取父页面的方法 1:方法没有参数(userInfor()) string userInfor = Convert.ToString(this.Page.GetType().GetMet ...
- .NET同页面内用户控件与父页面以及控件之间方法调用
用户控件调用父页面的方法: //获得父页面 Page p =this.Parent.Page; Type pageType = p.GetType(); //父页面的方法名 MethodInfo mi ...
- MFC 不同窗体之间变量调用
应用场景: (1)主对话框包含一个Tab控件,Tab控件用来切换显示若干子对话框,子对话框类的成员需要互相访问. (2)或者程序中包含多个类,各类之间需要互相访问. 方法1-定义指针成员变量: 详情参 ...
- Delphi窗体之间互相调用的简单问题
问题是这样的,我的程序主窗口Form1上面有一个数据连接(ADOCONNECTION1)和ADOQUERY,然后还有一些数据感知组件用于浏览用的,我打算点击From1中的一个“修改数据”按钮,就弹出F ...
- Iframe之间及iframe与父窗体之间值的传递
方法一:ScriptManager.RegisterClientScriptBlock(this,typeof(Page), "NoInformation", "wind ...
- c# 不同窗体之间传值和调用
1.子窗体事件刷新父窗体界面值 子窗体定义委托和事件 //声明一个委托 public delegate void DisplayUpdateDelegate(string str); //声明事件 p ...
- C#一个窗体调用另一个窗体的方法
一个窗体调用另一个窗体的方法:例如:窗体B要调用窗体A中的方法1.首先在窗体A中将窗体A设为静态窗体public static FormA m_formA; //设此窗体为静态,其他窗体可调用此 ...
- synchronized修饰的方法之间相互调用
1:synchronized修饰的方法之间相互调用,执行结果为There hello ..因为两个方法(main,hello)的synchronized形成了互斥锁. 所以当main方法执行完之后 ...
随机推荐
- dxteam团队项目终审报告
一. 团队成员的简介和个人博客地址 M1阶段 http://www.cnblogs.com/dxteam/p/3991514.html M2阶段 新成员 邓亚梅 http://www.cnblogs. ...
- windows上tomcat8的安装及配置
提示:在安装tomcat之前,确定安装好jdk. 一.下载tomcat8 http://tomcat.apache.org/download-80.cgi 点击这个网址 根据自己电脑的才做系统版本安装 ...
- 微信开发-charles抓包
在微信开发过程中有一块不能使用开发者工具进行调试,需要查看请求的返回,故使用了charles抓包工具. 环境配置 1.http://www.charlesproxy.com/getssl/ 下载cha ...
- The import * cannot be resolved
背景 使用eclipse jee做练习的时候,下载了老师的项目源码.考虑到老师用的时myeclipse,目录结构略有不同,所有不想直接导入项目,又考虑到,可能环境不一样,会出现这样那样的问题,所以我的 ...
- MySQL基础~~增、删、改、简单查
mysql> desc demo; +-----------+------------+------+-----+---------+----------------+ | Field | Ty ...
- GS环境里面 9999 常用密码的加密后的值
1. Test6530 APTZ5s6vrw1dglqO/63osA== 2. aaaaaa zgnewZXGGoqcPGtNpXTSXQ== 3. cwpass 3Me34S0+zY4xEGUFtz ...
- delphi7调用数据库连接属性
背景:连接数据库用ADOQuery控件,但是程序一旦编译完成,如果想更改数据库连接设置还得重新修改ADOQuery的属性重新编译 如果可以在程序中可以随时设置ADOQuery的属性则会方便很多. 实现 ...
- (C++)关于i++和i++的左值、右值问题
1.什么是左值和右值? 左值就是出现在表达式左边的值(等号左边),可以被改变,他是存储数据值的那块内存的地址,也称为变量的地址: 右值是指存储在某内存地址中的数据,也称为变量的数据. 左值可以作为右值 ...
- GitHub && GitLab
1.github介绍 Git作为一个开源的分布式版本控制系统,已经被越来越多的人使用,随之需要的就是需要有个专门的地方存储.管理通过Git上传的项目,这就是gitHub gitHub是一个面向开源及私 ...
- ansible系列5-开启加速 Ansible 执行速度的功能
SSH pipelining 是一个加速 Ansible 执行速度的简单方法.ssh pipelining 默认是关闭,之所以默认关闭是为了兼容不同的 sudo 配置,主要是 requiretty 选 ...