C# 子窗体中调用父窗体中的方法(或多窗体之间方法调用)
来源:互联网 发布:windows update不更新 编辑:程序博客网 时间:2024/05/01 23:58
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();
//来源:C/S框架网(www.csframework.com) QQ:1980854898
//父窗体是是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();
}
///<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
///<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
///<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模块。
- C# 子窗体中调用父窗体中的方法(或多窗体之间方法调用)
- C# 子窗体中调用父窗体中的方法(或多窗体之间方法调用)
- C# 子窗体中调用父窗体中的方法(或多窗体之间方法调用)
- 在子窗体中调用父窗体中的方法或属性(即在子窗体中刷新父窗体)
- C# WinForm 在父窗体与子窗体之间互相调用变量或方法
- iframe中的子窗体调用父窗体中的方法
- 主题:iframe中的子窗体调用父窗体中的方法
- C# 子窗体调用父窗体的方法
- C# 子窗体调用父窗体的方法
- C# 多窗体之间方法调用
- C# 窗体中 webbrowser 中 javascript 调用窗体方法 实例
- C#在一个窗体中调用另一个窗体的方法
- 子窗体调用父窗体的脚本方法
- C# 子窗体调用父窗体的方法
- C# 窗体中一个类中调用另一个窗体的控件或方法
- 子窗体调用父窗体
- 模式窗体调用用父窗体中的方法
- Web所有父窗体与子窗体的交互方法列举(子调用父窗体函数)
- PHP中str_replace()的用法
- MyEclipse创建WebService
- 锁定表头和固定列(Fixed table head and columns)
- Qt 无边框、透明、可移动、的个性窗体案例详解
- 【原创】国庆PE总复习(三)
- C# 子窗体中调用父窗体中的方法(或多窗体之间方法调用)
- Linux配置文件介绍
- uva10954 - Add All
- 在blackberry中载入图片使其在屏幕上显示的方法以及二维图形的绘制
- poj 1738 An old Stone Game(区间dp 合并石子问题直线型)
- 我的Java开发学习之旅------>Java ClassLoader解析一(转)
- java 时间转换
- Excel VBA用户窗体常用的方法
- Customising the Pentaho User Console (PUC)