简体   繁体   English

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

[英]calling one child form from another child form in c#

i have 3 forms: FormA ,FormB and FormC of which FormA is mdiParent form and form B and C are child forms. 我有3种形式:FormA,FormB和FormC,其中FormA是mdiParent形式,形式B和C是子形式。 i write the following code in FormA load event. 我在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();      
}

what i want is when i click a button on FormB, FormC should be shown. 我想要的是当我点击FormB上的一个按钮时,应该显示FormC。 now to do this will i need to create another instance of FormC in click event of button in FormB or should i be able to use the instancce created in FormA??? 现在要做到这一点,我需要在FormB中的按钮单击事件中创建另一个FormC实例,或者我应该能够使用在FormA中创建的实例?

if needed to create a separate instance then can someone plz explain the reason for doing so? 如果需要创建一个单独的实例,那么有人可以解释这样做的原因吗?

edit- the answer given by Oded suits me fine. 编辑 - Oded给出的答案很适合我。 but can i make the return type of the property as Form[] in order to add more than 1 references so that if i want to go back from FormC to FormB i can use similar method? 但是我可以将属性的返回类型设置为Form []以便添加多于1个引用,这样如果我想从FormC返回到FormB,我可以使用类似的方法吗?

also if i want to pass some data from FormB to FormC then how can i do that? 如果我想将一些数据从FormB传递给FormC,那么我该怎么办呢?

Your FormB needs a referenct to FormC . 您的FormB需要参考FormC

You can add a property on your FromB to do this: 您可以在FromB上添加属性来执行此操作:

public Form FormCRef {get;set;}

Then in your main form: 然后在你的主要形式:

formB.FormCRef = formC;

And in your FormB class do this in your event handler: 在您的FormB类中,在事件处理程序中执行此操作:

FormCRef.Show();

In FormA (MDIForm): 在FormA(MDIForm)中:

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

In FormB: 在FormB中:

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

You must use the instances created in FormA, because every form instance reperesnt a different form. 您必须使用在FormA中创建的实例,因为每个表单实例都会替换不同的表单。

The proper way to do this is expose an event FormB, have FormA register to it, and then FormA can call whatever you want on FormC: 正确的方法是公开FormB事件,将FormA注册到它,然后FormA可以在FormC上调用你想要的任何内容:

FormB: 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: // Save the form instances for future use, as private members of the class FormB formB; FormA: //保存表单实例以供将来使用,作为FormB formB的私有成员; FormB formC; 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();
}

An alternative, (and quite possibly controversial option) is to have the reference to each form stored as a static variable in each form. 另一种选择(并且很可能是有争议的选项)是将每个表单的引用存储为每种形式的静态变量。 If you are only ever going to want one instance of this form showing at any one time, then this method should be fine. 如果您只想要在任何时候显示此表单的一个实例,那么此方法应该没问题。 It is known as a Singleton pattern. 它被称为Singleton模式。

In form C have the following : 在表格C中有以下内容:

private static FormC thisForm = null;

public static FormC GetFormC()
{
  if (thisForm == null)
     thisForm = new FormC();

  return thisForm;
}

public static void ShowFormC()
{
  GetFormC().Show();
}

In Form A, if you need to do any set up on Form C call : 在表单A中,如果您需要在表单C上进行任何设置调用:

FormC.GetFormC().mdiParent = this;

And then in Form B, to show Form C make the following call : 然后在表单B中,显示表单C进行以下调用:

FormC.ShowFormC();

Its clean, clear, and if you are Absolutely Sure that you will only ever want one instance of FormC showing (which is what your code seems to be doing anyway), then it is the logical way! 它干净,清晰,如果你绝对确定你只需要一个FormC实例(这是你的代码似乎正在做什么),那么这是合乎逻辑的方式!

To reduce coupling the best practice would be to use the MessageBroker/EventBroker/EventAggregator pattern. 要减少耦合,最佳做法是使用MessageBroker / EventBroker / EventAggregator模式。 You cand find an implementation here or here 你可以在这里这里找到一个实现

Usage: 用法:

Declare the event class: 声明事件类:

public class ShowFormCEvent {}

Subcribe to the event in in FormA: 订阅FormA中的活动:

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

Fire the event in FormB 在FormB中触发事件

EventPublisher.Publish(new ShowFormCEvent());

It depends on the nature of your design: 这取决于您的设计的性质:

If it makes sense for FormB to talk to FormC directly, then FormB needs a reference to FormC. 如果FormB直接与FormC通信是有意义的,那么FormB需要引用FormC。 In this case I would think that maybe FormC should not be related to FormA, and instead FormB should be managing FormC. 在这种情况下,我认为FormC可能不应与FormA相关,而FormB应该管理FormC。 (Like if FormC was a tool window of FormB). (就像FormC是FormB的工具窗口一样)。

If it doesn't make sense for FormB to talk directly to FormC, then FormB should 'send a message' (call a method) up to FormA, and FormA should send the message to FormC. 如果FormB直接与FormC交谈没有意义,那么FormB应该向FormA“发送消息”(调用方法),FormA应该将消息发送给FormC。 ex: 例如:

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
    }
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM