Pratik Gandhi
Pratik Gandhi

Reputation: 247

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. i write the following code in FormA load event.

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

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

also if i want to pass some data from FormB to FormC then how can i do that?

Upvotes: 3

Views: 3874

Answers (6)

Edison
Edison

Reputation: 11

In FormA (MDIForm):

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

In FormB:

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

Upvotes: 1

Dave Cousineau
Dave Cousineau

Reputation: 13218

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. In this case I would think that maybe FormC should not be related to FormA, and instead FormB should be managing FormC. (Like if FormC was a tool window of 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. 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
    }
...

Upvotes: 0

Catalin DICU
Catalin DICU

Reputation: 4638

To reduce coupling the best practice would be to use the MessageBroker/EventBroker/EventAggregator pattern. You cand find an implementation here or here

Usage:

Declare the event class:

public class ShowFormCEvent {}

Subcribe to the event in in FormA:

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

Fire the event in FormB

EventPublisher.Publish(new ShowFormCEvent());

Upvotes: 0

Mongus Pong
Mongus Pong

Reputation: 11477

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.

In form C have the following :

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 :

FormC.GetFormC().mdiParent = this;

And then in Form B, to show Form C make the following call :

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!

Upvotes: 0

Amirshk
Amirshk

Reputation: 8258

You must use the instances created in FormA, because every form instance reperesnt a different form.

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:

// 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; 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();
}

Upvotes: 1

Oded
Oded

Reputation: 499382

Your FormB needs a referenct to FormC.

You can add a property on your FromB to do this:

public Form FormCRef {get;set;}

Then in your main form:

formB.FormCRef = formC;

And in your FormB class do this in your event handler:

FormCRef.Show();

Upvotes: 2

Related Questions