在c#中从另一个子表单调用一个子表单

我有3种forms:FormA,FormB和FormC,其中FormA是mdiParentforms,formsB和C是子forms。 我在FormA加载事件中编写以下代码。

private void frmMain_Load(object sender, EventArgs e) { formB.MdiParent = this; //formB is instance of FormB formC.MdiParent = this; //formC is instance of FormC formB.Show(); } 

我想要的是当我点击FormB上的一个按钮时,应该显示FormC。 现在要做到这一点,我需要在FormB中的按钮单击事件中创建另一个FormC实例,或者我应该能够使用在FormA中创建的实例?

如果需要创建一个单独的实例,那么有人可以解释这样做的原因吗?

编辑 – Oded给出的答案很适合我。 但是我可以将属性的返回类型设置为Form []以便添加多于1个引用,这样如果我想从FormC返回到FormB,我可以使用类似的方法吗?

如果我想将一些数据从FormB传递给FormC,那么我该怎么做呢?

您的FormB需要参考FormC

您可以在FromB上添加属性来执行此操作:

 public Form FormCRef {get;set;} 

然后在你的主要forms:

 formB.FormCRef = formC; 

在你的FormB类中,在事件处理程序中执行此操作:

 FormCRef.Show(); 

您必须使用在FormA中创建的实例,因为每个表单实例都会替换不同的表单。

执行此操作的正确方法是公开事件FormB,将FormA注册到它,然后FormA可以在FormC上调用您想要的任何内容:

FormB:

 // A delegate type for hooking up change notifications. public delegate void MagicEventHandler(); public event MagicEventHandler MagicButttonClicked; // Invoke the event, this inside your button click event handler: void Button1_OnClick(EventArgs e) { if (Changed != null) MagicButttonClicked(); } 

FormA: //保存表单实例以供将来使用,作为FormB formB的私有成员; FormB formC;

 OnLoad... { formB.MdiParent = this; //formB is instance of FormB formC.MagicButttonClicked += new On_MagicButttonClicked (); formC.MdiParent = this; //formC is instance of FormC formB.Show(); } public void On_MagicButttonClicked() { this.fromC.Activate(); } 

另一种选择(并且很可能是有争议的选项)是将每个表单的引用存储为每种forms的静态变量。 如果您只想要在任何时候显示此表单的一个实例,那么此方法应该没问题。 它被称为Singleton模式。

在表格C中有以下内容:

 private static FormC thisForm = null; public static FormC GetFormC() { if (thisForm == null) thisForm = new FormC(); return thisForm; } public static void ShowFormC() { GetFormC().Show(); } 

在表格A中,如果您需要在表格C上进行任何设置,请致电:

 FormC.GetFormC().mdiParent = this; 

然后在表单B中,显示表单C进行以下调用:

 FormC.ShowFormC(); 

它干净,清晰,如果你绝对确定你只需要一个FormC实例(这是你的代码似乎正在做什么),那么这是合乎逻辑的方式!

要减少耦合,最佳做法是使用MessageBroker / EventBroker / EventAggregator模式。 你可以在这里或这里找到一个实现

用法:

声明事件类:

 public class ShowFormCEvent {} 

订阅FormA中的活动:

 EventPublisher.Register(e=>formC.Show()); 

在FormB中触发事件

 EventPublisher.Publish(new ShowFormCEvent()); 

这取决于您的设计的性质:

如果FormB直接与FormC通信是有意义的,那么FormB需要引用FormC。 在这种情况下,我认为FormC可能不应该与FormA相关,而FormB应该管理FormC。 (就像FormC是FormB的工具窗口一样)。

如果FormB直接与FormC交谈没有意义,那么FormB应该向FormA“发送消息”(调用方法),FormA应该将消息发送给FormC。 例如:

 class FormB { ... private void SomethingHappened() { ((FormA)MdiParent).TellFormASomethingHappened(); } ... class FormA { private FormC mFormC; ... public void TellFormASomethingHappened() { mFormC.TellFormCSomethingHappened(); } ... class FormC { public void TellFormCSomethingHapened() { // do something } ... 

在FormA(MDIForm)中:

 FormB formB = new FormB(); formB.MdiParent = this; formB.Show(); 

在FormB中:

 FormC formC = new FormC(); formC.MdiParent = (FormA)this.ParentForm; formC.Show(); this.Close();