Windows Develop Bookmark and Share   
 index > Windows Forms Designer > Form hide/Unhide from another form - Correct Method??
 

Form hide/Unhide from another form - Correct Method??

Following information describes the application functionality.

1. The startup GUI(
Form1) which is inherited from Form Class is displayed at application startup.
2.
Form1 has a button which will start the actual application GUI.
3. The application GUI is inherited like this.
Form->BaseApplicationForm->TheGUIShownToUser.
4. So to show the application GUI I create an instance (Form2) of TheGUIShownToUser.
5. Now when the user clicks on Form1's button I want to hide the Form1 and display Form2.
6. Once user is done using the
Form2, the Form2 should be closed and Form1 should be shown again.

I have written the code, its working fine. But I want to know is this the
right way to do things??

How I did it:
In the Button Click event of the
Form1 I call the constructor of the Form2 and pass the parameter "this" to store theForm1 information in Form2. Then is hide the Form1 and show Form2. On the FormClosed event of the Form2 I call function on the Form1 information stored in Form2.

Code is below

//Form1.cs code

private void Button1_Click(object sender, EventArgs e)

{
string SelectedFilePath = "C:\abc.txt";
// create an object to store the current form information to pass as argument
TheGUIShownToUser Form2 = new TheGUIShownToUser(SelectedFilePath, this);
// hide the current form and show the study form
this.Hide();
Form2.Show();
}

//Form2.cs

private Form parentform;
public Form ParentForm
{

get
{

return parentform;
}
set
{

parentform = value;
}

}
public TheGUIShownToUser(string FileName, Form ParentControl)
{

// Store ParentForm information to show the parent form after exit.

ParentForm = ParentControl;
}
private void TheGUIShownToUser_FormClosed(object sender, FormClosedEventArgs e)
{

ParentForm.Show();

}

Questions:

1. In the TheGUIShownToUser class I have created a �/span>Form parentform�to store the Form1 information using “this�in Form1 function. Is this Right?
2. I initially used “object�and “control�class to store the information. The code using “object�is given below. Here I needed to typecast the object in closeevent to form. Is this appropriate or by doing this I lose information.
3. The “ParentForm�property is underlined green saying �strong style="">MyNamespace.Myclassname.ParentForm hides inherited member System.Windows.Forms.ContainerControl.ParentForm. Use the new keyword if hiding is intended.�What exactly does this mean? I have this class derived from base class which was further derived from Form class.

Code is below

//Form1.cs code

private void Button1_Click(object sender, EventArgs e)

{

string SelectedFilePath = "C:\abc.txt";
// create an object to store the current form information to pass as argument
object formInfo = this;

TheGUIShownToUser Form2= new TheGUIShownToUser(SelectedFilePath, formInfo);

// hide the current form and show the study form

this.Hide();

StudyForm.Show();

}


Form2.cs
private object parentform;

public object ParentForm

{
get
{

return parentform;

}

set

{

parentform = value;

}

}

public TheGUIShownToUser(string FileName, Form ParentControl)
{
ParentForm = ParentControl;
}

private void TheGUIShownToUser_FormClosed(object sender, FormClosedEventArgs e)
{

Form form = (Form) ParentForm;
ParentForm.Show();

}


Kavitesh Singh.
Kavitesh Singh  Monday, May 18, 2009 12:47 PM

Hi Kavitesh Singh,

I have read all your descriptions again and I think I got the key of your problem: You were looking for a way to make your control be able to use the caller in an common and reasonable way.

In this case, I think the way you did is right. The code below can explain your idea.

public partial class MyControl : UserControl

{

public MyControl()

{

InitializeComponent();

}

private Control _caller = null;

public Control Caller

{

get { return _caller; }

set { _caller = value; }

}

private void UseCallerToDoSomthing()

{

if (_caller != null)

{

if (_caller is Form)

{

//Do special thing to form.

}

else if (_caller is Control)

{

//Do special thing to control.

}

else

{

//Deal with other cases.

}

//Do the common operation to caller.

_caller.Show();

}

}

}

But in this case, you have to care about which type the caller is. I have another way below:

1. Define a interface to encapsulate all the functions and properties of a caller.

public interface ICaller

{

void Show();

}

2. Define your control which contains a property related to the caller.

public partial class MyControl2 : UserControl

{

public MyControl2()

{

InitializeComponent();

}

private Control _caller = null;

public Control Caller

{

get { return _caller; }

set { _caller = value; }

}

private void UseCallerToDoSomthing()

{

if (_caller != null)

{

//Do the common operation to caller.

_caller.Show();

}

}

}

3. All your callers must implement ICaller interface. For example:

public class Form1 : Form, ICaller

{

void ICaller.Show()

{

//Do special thing to form.

//Do the common operation to caller.

this.Show();

}

}

In the code snippet above, when your control want to use the caller to do a operation, it need not to care about which type the caller is, it only knows it’s a caller and has a method Show. In this case, the special operation is done in special type, but not in your control. So you only need to care about how to use a caller in your control.

Let me know if this helps.

Best Regards,

Aland Li


Please mark the replies as answers if they help and unmark if they don't.
Aland Li  Tuesday, May 26, 2009 2:25 AM
I posted the query on Windows Forms Forum. Somehow got no reply there.

Just posting the link to the post below:
http://social.msdn.microsoft.com/Forums/en-US/winformsdesigner/thread/64a17b18-ec59-416c-b683-00b48ac68eea

Would appreciate if someone can answer it.

Thanks.
Kavitesh Singh.
  • Merged byOmegaManMVPWednesday, May 20, 2009 2:23 PMPosted in C# group...somewhat of a duplicate post.
  •  
Kavitesh Singh  Wednesday, May 20, 2009 4:30 AM
Hi,
You only need to call the Hide/Show method of that particular form. That is a correct method only. We will see if you got any error while using this method.


-- Thanks Ajith R [Remember to Mark as Answer if it is Helpful.]
Ajith R Nair  Wednesday, May 20, 2009 4:58 AM
Like i mentioned in the post. I am not getting errors. I have compiled and code is working fine.

I wanted to get advice on the approach. In one i use Object class and in other in used Form class. For object i had to typecast to Form and then use show/hide method.
The point to consider is the form being displayed from another form is derived class of Form.
Kavitesh Singh.
Kavitesh Singh  Wednesday, May 20, 2009 5:02 AM

After reading your question, I think the code you wrote can work, but there is a little problem. You added a property named �/span>ParentForm�/span> in Form2, but as we know, the base class Form already has this property, so your property will hide the one in base class, which may lead some errors in the future. You can use Show(IWin32Window owner) method in form1 and need not add an property to from2 to store form1, the Owner property of form2 will contain form1. I did a little change in your code below

Form1.cs

private void button1_Click(object sender, EventArgs e)

{

Form2 form = new Form2();

form.Show(this); // this will set the Owner of form(Form2) to this(Form1)

this.Hide();

}

Form2.cs

private void Form2_FormClosed(object sender, FormClosedEventArgs e)

{

this.Owner.Show();

}

Let me know if this helps.
Please mark the replies as answers if they help and unmark if they don't.
Aland Li  Wednesday, May 20, 2009 9:39 AM
Your approach also gave same results and the application is working fine.
The whole thought process originated because one of the forms was derived from form class. And then typecasting to the Form instead of derived class might have resulted in some loss of data(in my view). So i had put the question.
Kavitesh Singh.
Kavitesh Singh  Wednesday, May 20, 2009 9:51 AM
I suggest that you modify your approach.
Make your app into MdiParent/Child application.

Create a third form, an MdiParent form.
Let thisparent forminstantiate and display either of your 2 forms, which will now be child forms.
Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, May 20, 2009 12:53 PM
Its a small utility program and i didnt want to have overhead of MDI.

The first screen actually loads the files from which user can select which one to open or edit. Once the selection is made it displays another screen displaying the contents. Now you may think application is somewhat similar to notepad etc. Its basically used to learn new words to enhance vocabulary. So first one would show alphabetically the Word List files and then user can proceed learning it.

Once i am done, application would anyways be free :)

Kavitesh Singh.
Kavitesh Singh  Wednesday, May 20, 2009 12:59 PM

Overhead? What overhead?
I thinking you are trading "less overhead" for "more headache".

Plus you will be creating forms that are tightly coupled to each other.
Adding new features existing forms and new forms will be a nightmare.

Think about this for a second.
What if the Parent had no menu, while the always maximixed child forms did have menus?


Mark the best replies as answers. "Fooling computers since 1971."
Rudedog2  Wednesday, May 20, 2009 1:24 PM
Lets keep the MDI approach aside for a while. Though, i do understand your point why i should opt for MDI.

Would like to stick to SDI approach for a while. Actually more than programming SDI/MDI i wanted to get the concept cleared of using a derived class and typecasting to parent class and use it.

Kavitesh Singh.
Kavitesh Singh  Wednesday, May 20, 2009 4:56 PM

Based on my understanding, you are concernedabout the relationship between a derived class and its parent and how to use them correctly.

When the property is base class and you want to use derived class to get more functions, you can use ‘as�key word to convert it to derived class. Here is an example:

Fom1.cs

private void button1_Click(object sender, EventArgs e)

{

Form2 form = new Form2();

form.Show(this); // this will set the Owner of form(Form2) to this(Form1)

this.Hide();

}

public string Descript

{

get { return "The base class."; }

}

Form2.cs

private void Form2_FormClosed(object sender, FormClosedEventArgs e)

{

//Convert the parent form to accurate type and use special functions.

Form1 parent = this.Owner as Form1;

if (parent != null)

MessageBox.Show(parent.Descript);

this.Owner.Show();

}

Let me know if this helps.

Best regards,

AlandLi


Please mark the replies as answers if they help and unmark if they don't.
Aland Li  Friday, May 22, 2009 8:21 AM
Hi Aland Li,

In this case above i know prior that it will be a Form1 class derived from Form class. Hence this solution works fine :)

It may sound confusing, but is there a way to generalize it?? I mean say i am trying to make a control whichi can redistribute. Now i dont know what user has called my control from. It could be normal Form, panel,button or some derived class. To save the handle of the calling control i can use some property and then call a method like .Show() which is present in all the controls or forms.
Kavitesh Singh.
Kavitesh Singh  Monday, May 25, 2009 9:40 AM

Hi Kavitesh Singh,

I have read all your descriptions again and I think I got the key of your problem: You were looking for a way to make your control be able to use the caller in an common and reasonable way.

In this case, I think the way you did is right. The code below can explain your idea.

public partial class MyControl : UserControl

{

public MyControl()

{

InitializeComponent();

}

private Control _caller = null;

public Control Caller

{

get { return _caller; }

set { _caller = value; }

}

private void UseCallerToDoSomthing()

{

if (_caller != null)

{

if (_caller is Form)

{

//Do special thing to form.

}

else if (_caller is Control)

{

//Do special thing to control.

}

else

{

//Deal with other cases.

}

//Do the common operation to caller.

_caller.Show();

}

}

}

But in this case, you have to care about which type the caller is. I have another way below:

1. Define a interface to encapsulate all the functions and properties of a caller.

public interface ICaller

{

void Show();

}

2. Define your control which contains a property related to the caller.

public partial class MyControl2 : UserControl

{

public MyControl2()

{

InitializeComponent();

}

private Control _caller = null;

public Control Caller

{

get { return _caller; }

set { _caller = value; }

}

private void UseCallerToDoSomthing()

{

if (_caller != null)

{

//Do the common operation to caller.

_caller.Show();

}

}

}

3. All your callers must implement ICaller interface. For example:

public class Form1 : Form, ICaller

{

void ICaller.Show()

{

//Do special thing to form.

//Do the common operation to caller.

this.Show();

}

}

In the code snippet above, when your control want to use the caller to do a operation, it need not to care about which type the caller is, it only knows it’s a caller and has a method Show. In this case, the special operation is done in special type, but not in your control. So you only need to care about how to use a caller in your control.

Let me know if this helps.

Best Regards,

Aland Li


Please mark the replies as answers if they help and unmark if they don't.
Aland Li  Tuesday, May 26, 2009 2:25 AM
Thanks a lot Aland Li. The last solution was something i was looking for. I appreciate your help in this. Thanks a lot once again.
Kavitesh Singh.
Kavitesh Singh  Tuesday, May 26, 2009 3:58 AM

You can use google to search for other answers

Custom Search

More Threads

• Windows Form Designer bug in causing an event handler to disappear, C# example
• setting negative padding for header text in datagridview control.
• COM Interopt - is it all STA or single threaded?
• Definition of CommandLine(0)="Name".
• table layout panel bug /issue the controls swap at runtime.
• Problem while clicking in Windows Form
• inheriting from an existing Windows Forms control
• Windows application with HtML Templates
• Making a PointFConverter
• Is there container or controls mangering the process running