tags:

views:

343

answers:

4

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?

+2  A: 

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();
Oded
+1, i don't like using form references if not mandatory, but it's a good solution
Am
do i need to write anything in the property FormCRef or should leave it the way as u hav written??? sorry for asking such simple question but i have never created any property before so don't know much about them.
Pratik Gandhi
@Pratik Gandhi - the syntax I used is fine. It is called Automatic Properties and was introduced in C# 3.0.
Oded
@Oded-actually i am using VS2005 and .Net Framework and ver 2.0, so will that be a problem?
Pratik Gandhi
@Pratik Gandhi - You will have to create a backing field and create the property as normal, that's all.
Oded
+1  A: 

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();
}
Am
A: 

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!

Mongus Pong
A: 

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());
Catalin DICU