Reputation: 247
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
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
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
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
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
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
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