It is a common design in data handling applications to move from form to form to show the user different information.
I have seen any number of different attempts at this on the boards so i thought I'd throw together a short snippet to show a cleaner OO way to do this.

This example is designed to hide the parent form whilst a child form is displayed then to redisplay the parent when the child is closed. In this instance, no data is passed between the parent and the child. To see how to do this check my tutorial for accessing controls between forms :)

The important feature of this snippet is the event handler attached to the instance of the child. By handling this event in the parent the child has no knowledge of the calling parent form.

If you wish to close the parent and never redisplay it you can amend the event handler to this.Close() instead of this.Show(). This will close the calling form when the child is closed.

Comments
Nicely done
Keep up the good work!
public partial class Parent : Form
{
    public Parent()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        Child child = new Child(); //create new isntance of form
        child.FormClosed += new FormClosedEventHandler(child_FormClosed); //add handler to catch when child form is closed
        child.Show(); //show child
        this.Hide(); //hide parent
    }

    void child_FormClosed(object sender, FormClosedEventArgs e)
    {
        //when child form is closed, the parent reappears
        this.Show(); 
    }
}

how do you create child forms? is this any different from creating new windows forms? I tried this method on an existing application, but visual studio 2010 ultimate does not recognise Child as a valid type.
It says:
The type or namespace 'Child' could not be found (are you missing a using directive or an assembly reference?)

Is there a using directive that you need to put to use Child, or is there a special way of creating new forms as children of the current one?

Or if you rename the class in Form 2 from "public partial class Form2 : Form"
to
"public partial class Child : Form"

and change the initializeComponent call as well.

But how do you accomplish this with more than 2 forms? The name Child clashes.

Dan I think jayxx1234 hit the soft point here with multiple child frames ;)

I'm not C# developer (last touch it at university) but based on my OO knowledge of Java I believe your approach is not that good. Instead of hiding and showing different I would rather keep same panel with the form and just swapped around panels with the fields/buttons/radio/check (it is my understanding in C# you have panel inside form and form inside frame, where in Java it is simpler no form at all I would see it as obsolete)

"Child" is just what i named my second form class to highlight the Parent - Child relationship. You are correct, you need to rename your second form or change "Child child = new Child()" to "yourFormType child = new yourFormType()" where yourFormType is the name of the form you are calling.
This snippet was intended to highlight th use of events to hide/show forms in an OO way, it wasn't intended to teach people how to instantiate forms.

I never claimed this method would work with multiple forms. It is an OO approach to hiding the current form when a single child form is displayed. If you tried this with multiple child forms then the parent would reappear after any of them are closed.

@peter_budo, you have the concept slightly scewed; a Form is the same as the Frame in java. In C# you can have panels to divide up a form so you can use the approach you mentioned and cycle through different panels on the same form but that is terrible in terms of OO. If each panel represents a distinct concept then you should have them in distinct classes. By using seperate Forms you can reuse the form any time you need to work with that concept.

@Ryshad, no form and frame are not same ;) and if there was form, like in JME but not in JSE, it would hold only input fields as we know from web design for example and not any visual component. I wouldn't be sure about "scewed" concepts, besides you C# boys need to catch up on OO :twisted:

Sorry, I haven't used Java since i graduated. I was going by this, the description matches that of a C# Form which is the window into which we place our visual components.

@Ryshad are 'Parent' and 'Child' specifically designating the forms as having a parent-child relationship, or is this just to show the user of their relationship (when any child is closed, Parent shows)?

I was under the impression (as I am relatively new to c# and programming in general) that visual studio identified the forms as having a parent-child relationship, and thus the 'children' forms inherited stuff from the 'parent'. This is what I was told in a similar forum topic.

I named them as Parent and Child to highlight the relationship.
This example was specifically intended for showing a single child from the parent. You can use it to chain forms to mimic a forward/backward function; ie, in Form1 you create Form2 then show Form2 and hide Form1. In Form2 you create Form3 then show Form3 and hide Form2. Now when you close Form3, Form2 is redisplayed and when you close Form2 you return to Form1.
The code allows you to recall Form1 when Form2 closes without Form2 having to hold a reference to Form1 or having to find a reference to Form1 in the OpenForms collection etc.

aah, ok. So 'Parent' and 'Child' were just to show the user/reader what you just said, not to tell the compiler to do anything special?

Thats right. I could just have easily called the classes Foo and Bar or Form1 and Form2. The name you chose should be descriptive of what the class/form does...in this case the only thing they really do is show a Parent and Child relationship :)

The name you chose should be descriptive of what the class/form does

Yeah, I guess. Personally I never bother, but that will most likely change when I get on to bigger programs with many forms. As for now, I am just beginning using multiple forms, which is why I know so little.

When you are working with a single form it doesnt really matter what you call it, but when you get onto larger projects you will need to name things clearly. Its a good habit to get into early on...old habits are hard to break. Pick a naming convention and stick with it. Theres a nice reference for some of the common naming conventions here.

Form1 frm1=new form1;
frm1.show();
this.hid();

very useful Try it

So, I take it you didn't read any of the discussion that accompanied this snippet as it was explained that it goes beyond the simple process you provided here.

S'all good though, I can understand how spending an extra 1-2 minutes of reading can be a horrible waste of one's day :twisted:

Form1 frm1=new form1;
frm1.show();
this.hid();

very useful Try it

First of all, if you read the introduction to the snippet and the discussion that followed you might have seen that this code is intended to show the first form automatically when the second form is closed without the second form needing to hold a reference to the first.
Secondly, if you post code, please take the time to spell check it (this.hid();) and put it in [code]

[/code] tags to preserve its formatting.

Edited 6 Years Ago by Geekitygeek: n/a

i think that line is useless

child.FormClosed += new FormClosedEventHandler(child_FormClosed);

why would you need this?

Bogdan, the author is creating two independent forms, that are designed to be independent. Event processors are delegate handlers. You subscribe software by adding it to the event. In this case "child_FormClosed" is a subroutine that is built and owned by the parent form. By subscribing the child's FormClosed event to it, the child doesn't care that the delegate is owned by by another form, when it closes, it calls this event and does nothing further with the child form other than closing it. Normally this is used to clean-up a form gracefully before it gets close. The child could also do this and both functions would fire when the child was closed. When the parent form is hidden in the button event that creates the new child form, it remains active but completely inaccessable to the user. It would remain that way until you shut down the sever without this event. But because it is owned by the parent, the parent executes the code to allow you to access the form because it now becomes visible.

Why you need this, is to inform the parent form to again give user control in the parent form instead of becoming a sneaky memory leak where GC is supposed to solve that problem.

Sorry, Events and Event Handlers are two different things, you subscribe to the handler to call a routine when the event is triggered.

Great, it works really fine, cos if you hide a form and then when you what to come back, if in the other form you use:
FirstForm Form1 = new FirstForm
Form1.show()

you dont come back to the hided form, you opend a new instance of that form.

The article starter has earned a lot of community kudos, and such articles offer a bounty for quality replies.