I am trying to create a two-form Windows Application in C#. For simplicity and to help me figure it out before using it elsewhere, I have essentially created a Windows form application with two forms: Form1 and Form2, Form1 showing on startup. At the click of a button, I can get Form1 to "disappear" and Form2:
private void button1_Click(object sender, EventArgs e)
{
Form2 x = new Form2();
x.Show();
this.Hide();
}
And this works great. However, when I want to return to Form1 (by making it visible again) and unload Form2, I am unsure how to proceed with coding Form2 to return the user to Form1 using a button click as well. I'm not sure what to refer to to make that form visible again, instead of having to create a new Form1 and loading it, thereby leaving my original startup form sitting in memory.
Any help you can provide would be awesome! Thanks in advance,
-Jan
As Alfie comment suggests, you need to control your instances of each form somehow.
I'd suggest a static class with two variables. When you start up you link the forms to these public properties in the static class.
something like this:
public static class App {
public static Form Form1;
public static Form Form2;
}
on startup or the click method, you'd say something like:
private void button1_Click(object sender, EventArgs e)
{
if (App.Form1 != null)
{
App.Form1 = new Form1();
}
App.Form1.Show();
App.Form2.Hide();
}
Do this:
private void button1_Click(object sender, EventArgs e)
{
Form2 x = new Form2();
this.Hide();
x.ShowModal();
this.Show();
}
Related
I designed a form for login that named as form1, and have 2 more form form2,form3
form2 items showing in panel from form1
and what I want to do
when I click the button in panel ( the item from form2 ) want to show form2 and hide form1 but the code isnt working
private void button1_Click(object sender, EventArgs e)
{
Form1 frm1 = new Form1();
Form3 frm3 = new Form3();
frm1.Hide();
frm3.Show();
};
form3 is opening but form1 isnt hiding
Its not hiding because you created a new instance for form1 which is already instantiated.
You must call the Hide() method on the same instance used to call the Show() method.
If you added this code inside form1 class ,then change it like this
private Form1 frm1
public Form2()
{
frm1 = new Form1()
}
private void button_show_form1_Click(object sender, EventArgs e)
{
frm1.Show();
};
private void button1_Click(object sender, EventArgs e)
{
Form3 frm3 = new Form3();
frm3.Show();
frm1.Hide();
};
You creating both forms in your codesnipped. Form1 is not the form you want to close, i think. frm1 is only another instance of Form1, but not the openend instance von Form1. You must have anywhere another instance of Form1. You must use the right referenz to the right instance.
It is important to know that WinForms create an instance of the startup form. In our case the startup form would be Form1. So, when you say
Form1 frm1 = new Form1();
You're actually creating a new (second) instance of Form1. This means that, in code, there are two different Form1's.
What we want to do is check with our application to get the instance of Form1 that already exists.
// This goes in Form2. It returns an instance of Form1, if it exists.
private Form getForm1()
{
// Application holds information about our application, such as which forms are currently open.
var formCollection = System.Windows.Forms.Application.OpenForms;
// Now we loop through the open forms in search of the form we want, Form1.
foreach (Form frm in formCollection)
{
if (frm.Name.Equals("Form1"))
{
return frm;
}
}
return null;
}
Now that we can get the existing instance of Form1 we can use it to make the form hidden.
private void button1_Click(object sender, EventArgs e)
{
var form1 = getForm1();
if (form1 != null) form1.Hide();
}
Something to know here is that when a form is hidden it is not closed. So, we need to make sure that Form1 becomes visible again. For example, we can set Form1 to be visible when Form2 closes.
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
// The question mark (?) checks to see if the result of
// getForm1() is null. Same thing that is happening in
// button1_click
getForm1()?.Show();
}
Complete Form2 Code
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var frm1 = getForm1();
var frm3 = new Form3();
if (frm1 != null) frm1.Hide();
frm3.Show();
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
// The question mark (?) checks to see if the result of getForm1() is null. Same thing that is happening in button1_click
getForm1()?.Show();
}
// This goes in Form2. It returns an instance of Form1, if it exists.
private Form getForm1()
{
// Application holds information about our application, such as which forms are currently open.
// Note that Open and Visible have different definitions.
var formCollection = System.Windows.Forms.Application.OpenForms;
// Now we loop through the open forms in search of the form we want, Form1.
foreach (Form frm in formCollection)
{
if (frm.Name.Equals("Form1"))
{
return frm;
}
}
return null;
}
}
I have 2 forms:
Form1 that make a screenshot.
Form2 that have 2 buttons to manipulate the screenshot created by form1.
Form1 also have a "hidden" button that contain the method to save the screenshot.
My questions:
How can i click the form1's button from form2?
and
How can i check when the form1 is closed and then close form2 too?
I've tried something like this but nothing happens when i click form2 save button:
var form = Form.ActiveForm as Form1;
if (form != null)
{
form.button1.PerformClick();
}
First of all the normal way multiple forms work is that when you close down the Startup form then the secondary forms will close also. If you are creating your Form2 in Form1 I would show it by using (your second Forms Instance).Show(this). You could then access the Form by Form2's Parent Property. i.e.
var form = (Form1)this.Owner();
You should then be able to access all of the public methods of Form1, Also I would take the code that you are using to save your screenshot and put into a public method, no need to have it in a Button's click event especially if the button is hidden.
Here is a quick example:
Form1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Show(this);
}
}
Form2
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var frm = (Form1)this.Owner;
if (frm != null)
frm.button1.PerformClick();
}
}
Instead of making a hidden button just make a method not linked to a button.
In Form1.cs:
public void SaveScreenshot()
{
//TODO: Save the Screenshot
}
In Form2.cs:
Form1 form = Application.OpenForms.OfType<Form1>().FirstOrDefault();
if (form != null) {
form.SaveScreenshot();
}
Also make sure to declare the SaveScreenshot method as public or internal.
I changed the code that gets Form1. If you click a button on Form2 then Form2 will be the ActiveForm, so your code will never "see" Form1. I used LINQ methods in my code that will only work if you have a using System.Linq; at the top of your code.
I have a project, where a wizard form is called to make a project. On the end of the wizard I want to send a 'world' object back to a variable in the Main form. But If I give the main form with it through the constructor I can't access it's methods or properties. Am I doing something wrong?
here is my code:
main form
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
this.NewProject();
}
private void NewProject()
{
var myForm = new ProjectWizard(this);
myForm.Show();
}
Wizard form code:
public ProjectWizard(Form form)
{
InitializeComponent();
MainForm = form;
}
private void finishButton_Click(object sender, EventArgs e)
{
//World world = new World();
//MainForm.CurrentWorld = world;
}
Thanks in advance.
You just need to make CurrentWorld public or internal on the MainForm class. Honestly, you're doing everything else right!
UPDATE: also make sure that the MainForm private field declared in Form1 is of the type MainForm and not just Form. So, change the constructor a tidge too:
public ProjectWizard(MainForm form)
I am working on a game that utilizes Windows Forms in C#. I want to be able to use the first form to call a second form. I have this working. Then I would like for the second form to send data back to the first form rather than creating a new instance of the first form. Can this be done? I know I need to have my properties set up so that I can set the variables from one form to the other. I am just not sure how to go about calling the first form without creating a new instance of it.
Is there a way that this can be done?
For example if I have Form A create an instance of Form B, can I have Form B do some work and send the data back to the original Form A without creating a new instance of Form A?
If you don't use the Data sent back Form A right away then you could use the Form_Closing event handler Form B and then a public property in Form B also.
In your Form A it could look like this:
public partial class FormA : Form
{
FormB frmB = new FormB(); // Instantiate FormB so that you could create an event handler in the constructor
public FormA()
{
InitializeComponent();
// Event Handler for Form Closing
frmB.FormClosing += new FormClosingEventHandler(frmB_FormClosing);
}
void frmB_FormClosing(object sender, FormClosingEventArgs e)
{
String fromFormB = frm2.FormBData; // Get Data from Form B when form is about to close
}
private void button1_Click(object sender, EventArgs e)
{
frmB.ShowDialog(); // Showing Form B
}
}
And in your Form B it could look like this:
private void button1_Click(object sender, EventArgs e)
{
// Let just say that the data is sent back once you click a button
FormBData = "Hello World!";
Close();
}
public String FormBData { get; set; }
It's hard to say without knowing your full requirements. But generally I go like this (Somewhat psuedo code).
Form2 dialogForm = new Form2();
if(dialogForm.ShowDialog() == DialogResult.OK)
{
this.PropertyOnForm1 = dialogForm.PropertyOnForm2
}
This ofcourse relies that your second form is a dialog. You will need to set the dialogresult buttons on Form2, and have a public property that will be accessed from Form1 once the dialog has been completed.
Let me know if this doesn't work and I'll write up a different answer.
Since you are creating Form2 in Form1, you can create a custom event in Form2 and subscribe to it in Form1 at the time that you create Form2, if you are returning information from Form2 when you are closing it then Edper's or MindingData's answers will work.
Here is a quick and dirty example using EventHandler<TEventArgs>
Form1
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.myCustomEvent += frm2_myCustomEvent;
frm2.Show();
}
void frm2_myCustomEvent(object sender, string e)
{
this.Text = e;
}
}
Form2
public partial class Form2 : Form
{
public event EventHandler<string> myCustomEvent;
int count;
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
count +=1;
myCustomEvent(sender, count.ToString());
}
}
I am a newbiest in c# and window form
i am doing a project and i meet some problem
how can i navigate forms within the window( i have a menu strip, when click it will show a item "Brand", so when i click it, it should open up within the window , i don't want something using the mdiparent/container, i have form1 and form2, then i put the menu strip in form1, which there is some thing inside form1, if use the mdiparent/container, the form1 content/thing will block the form2 )
2.i use the below code and the problem is i want to close the form1 which i click on " Brand" in the menu strip...but how???
public partial class Form1 : Form
{
// i put the menu strip in form1 design
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void Check_Click(object sender, EventArgs e)
{
Form2 Check = new Form2();
Check.Show();
}
}
You cannot just close the Form1 as it is the main form, but you can hide it. Use this.Hide().
private void Check_Click(object sender, EventArgs e)
{
Form2 Check= new Form2();
Check.Show();
Hide();
}
[EDIT]
Not sure if this is what is asked. But...
There are many ways to implement navigation between forms, for example:
In Form1:
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Tag = this;
form2.Show(this);
Hide();
}
In Form2:
private void button1_Click(object sender, EventArgs e)
{
var form1 = (Form1)Tag;
form1.Show();
Close();
}
I think you should create usercontrols rather than different forms. Then you can add your usercontrols in your main panel according to the selection in the menu.
Initially something like below
this.panel.Controls.Clear();
this.panel.Controls.Add(new UserControl_For_Form1());
Once the user click some other selection in menu.
this.panel.Controls.Clear();
this.panel.Controls.Add(new UserControl_For_Form2());
If you really want to use the way that you are using at the moment. Below code will help.
Add a Form1 property for the Form2 and parse the form1 instance to the Form2 with its constructor.
public partial class Form2 : Form
{
private Form1 form1;
public Form2(Form1 myForm)
{
InitializeComponent();
form1 = myForm;
}
}
Show the form2 and hide the form1.
private void Check_Click(object sender, EventArgs e)
{
Form2 Check= new Form2(this);
Check.Show();
Hide();
}
In form2 closing event now you can show the form1 instance which is in the form2 and close the form2.
Using of MDI form is another option for you.
It has been 7 years since this question was asked but I wanna give an answer in case if someone is still looking for a solution. If you are using DevExpress, you can add Navigation Frame to your program. You can switch between different components such as GridControl, GroupBox and so on. So you dont have to create an extra form in order to navigate between forms.