how to hide form1 by clicking button in form2 - c#

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;
}
}

Related

How to close a sub form from another sub form without closing main form c#

After open FORM 2.dialog from FORM 1, I want to close FORM 1 via button from FORM 2.
FORM 1
private void btnaddIPrange_Click(object sender, EventArgs e)
{
new form2().ShowDialog();
}
FORM 2
private void btnIPRangeCancel_Click(object sender, EventArgs e)
{
//close FORM 1(I don't know the code to close it)
this.Close();
}
Form2 will need a reference to Form1. You can do that several ways.
For example, in Form1 you set the Owner property of the new Form2 instance to this:
private void btnaddIPrange_Click(object sender, EventArgs e)
{
Form2 myForm = new Form2(); // Creates instance of Form2.
myForm.Owner = this; // Assigns reference to this instance of Form1 to the Owner property of Form2.
myForm.Show(); // Opens Form2 instance.
// You can also call myForm.Show(this);
// instead of the above two lines to automatically assign this form as the owner.
}
Then in Form2:
private void btnIPRangeCancel_Click(object sender, EventArgs e)
{
if(this.Owner != null) // Check for null.
this.Owner.Close(); // Closes Form1 instance.
this.Close(); // Closes current Form2 instance.
}
If all your forms are members of the same parent form, you can just call:
var ParentalForm = this.ParentForm as Foo_MainForm;
Make sure the child forms are public/internal members on the form.
Then:
ParentalForm.Foo_FormWantingClosed.Close();
Or in just one line:
(this.ParentForm as Foo_MainForm).Foo_FormWantingClosed.Close();
Off the top of my head.
Another idea! Since the form1 is sender, you can cast the object as form1 and close it directly. For instance:
private void OpenForm2(object sender, EventArgs e)
{
var callingForm = sender as form1;
if (callingForm != null)
{
callingForm.Close();
}
this.Close();
}

How to get the value from active form to another form on UserControl using delegate

My Winform application has 3 form: MainForm, Form1 and Form2.
MainForm has an UserControl; when application starts, it calls MainForm, MainForm will be loaded and added Form1 onto UserControl:
private void MainForm_Load(object sender, EventArgs e)
{
Form1 frm = new Form1() { Dock = DockStyle.Fill, TopLevel = false, Visible = true };
xtraUserControl1.Controls.Add(frm);
}
On Form1, I use delegate:
public delegate void Tranferdata(string txt);
public Tranferdata _tranfer;
private void Gettxt(string txt)
{
tbx_Recieve.Text = txt;
}
Form1 has a button to call Form2:
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.ShowDialog(this);
}
Form2 will send value to Form1 after closed, Code on Form2:
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
{
using (Form1 frm1 = (Form1)this.Owner)
{
frm1._tranfer(tbx_Numb.Text);
}
}
private void button1_Click_1(object sender, EventArgs e)
{
this.Close();
}
But my code doesn't work correctly. It crashed at 'using (Form1 frm1 = (Form1)this.Owner)' and show the System.InvalidCastException.
How can I fix this?
The reason it crashed on that line is because you didn't set Form1 to be the owner of Form2.
To fix, first have Form1 as a class variable and not as a local variable:
Form1 form1;
private void MainForm_Load(object sender, EventArgs e)
{
form1 = new Form1() { Dock = DockStyle.Fill, TopLevel = false, Visible = true };
xtraUserControl1.Controls.Add(form1);
}
Then you can use it to assign Form2's owner when you create it:
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.Owner = form1;
frm2.ShowDialog(this);
}
And also, like Ron Beyer mentioned in his comment, consider removing the using statement, it will close Form1, it doesn't sound like that's what you want to do.
Now, while that approach will work, there are some questions that you should consider here:
Why did you choose to use the "Owner" property in the first place? Do you really need it? Having Form1 as the owner of Form2 means that Form2 will close when Form1 is closed. Since you use ShowDialog on Form2 it will block the user from closing Form1 while Form2 is showing so it seems unneeded.
If the reason for using the Owner property is just for the sake of using the delegate than you could have just added a property to Form2 to be of type Form1, which would have given you type safety and superior code.
But there is even a better way: MainForm can register to the Closed event for Form2 and call the method on Form1. This will remove unneeded dependencies (Form2 and Form1 will not know about each other at all) making the code healthier.
I found the solution to this problem:
In the Form 2:
public void SetParent(Form1 frm)
{
frm1 = frm;
}
and call it in Form 1 at event call form2:
private void button1_Click(object sender, EventArgs e)
{
Form2 frm2 = new Form2();
frm2.SetParent(this);
frm2.ShowDialog();
}

Add/Remove a control from another Form - C#

How to Add or Remove a control from another form that is active and currently showing? I am using the following code:
private void button2_Click(object sender, EventArgs e)
{
Form1 frm1 = new Form1();
frm1.Controls.RemoveByKey("button1");
}
But it is not working because of new initialization of Form1.
If the form, from which a control is to be removed, is a child of another form you can access the form through the OwnedForms property. And after accessing it, you can remove controls from it. For example
Form1
private void button1_Click(object sender, EventArgs e)
{
var form = new Form3 { Owner = this };
form.Show();
}
private void button2_Click(object sender, EventArgs e)
{
if(OwnedForms.Length > 0)
{
var form = OwnedForms[0];
//assuming there's a control with id 'One':
form.Controls.RemoveByKey("One");
}
}
From the comments, it is clear that Form2 does not have a reference to Form1.
You didn't post any code on how you are displaying Form2, but here is an example on how it could work by passing the reference through the constructor:
public class Form2 : Form {
private Form1 _Form1;
public TestForm(Form1 form1) {
InitializeComponent();
_Form1 = form1; // <- this is the reference from Form1
}
}
Then your removing action on Form2 would look like this:
private void button2_Click(object sender, EventArgs e) {
_Form1.Controls.RemoveByKey("button1");
}
When creating Form2 from Form1, this is an example on how it would be passed:
private Form2 _Form2;
private void button1_Click(object sender, EventArgs e) {
_Form2 = new Form2(this); // <- this is the reference of Form1 you are passing
_Form2.Show();
}
As you already know you need the one instance of Form1.
If this is your main form and you used the Visual Studio wizard to create a Windows Forms Application you can look in the Program class. There is usually the main form built.
Now you need to assign the new Form1() expression to a variable and assign it to the second form with button button2.

A blocking/unblocking winforms call

I am currently facing this scenario and i need your help :
Having two winForms Form1 and Form2, a click button's event on form1 will launch form2.
I want to launch form2 and close (dispose) form1.
I have two ways to call form2 :
1) Using a blocking call with ShowDialog();
namespace programm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void callForm2bt_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.ShowDialog();
this.Close();
}
}
}
In this case, once form2 is called i can't close (dispose) form1.
2) Using an unblocking call with Show() ;
namespace programm
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void callForm2bt_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Show();
this.Close();
}
}
}
In this case, once form1 is closed ( disposed) it dispose automatically form2.
Any idea how to dispose form1 and keeping form2 functional ?
Thanks
Either do the inverse: run the Form2 as the main form, and set its visibility to false, and start Form1 from it, and when finished from Form1 close it and set the Form2 visibility to true. So:
static void Main()
{
...
Application.Run(new Form2());//instead of Form1
}
public class Form2 ...
{
//At From2.Load:
private void Form2_Load(object sender, EventArgs e)
{
this.Hide();//the form2 will hide and show the form 1.
Form1 form1 = new Form1(this);
form1.Show();
}
}
public class Form1...
{
private Form2 _form2 = null;
public Form1()
{ InitializeComponents();}
public Form1(Form2 form2) : this()
{
_form2 = form2;
}
private void callForm2bt_Click(object sender, EventArgs e)
{
if (_form2 != null)
{
_form2.Show();
}
this.Close();
}
}
Or use your current method but don't close the Form1, instead set its visability to false when you finished from it. by calling this.Hide(); or this.Visable = false; Like:
private void callForm2bt_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Show();
this.Hide();//this will hide the control from the user but it will still alive.
}
Edit: At the first solution you can also use form1.ShowDialog() and get rid from passing Form2 instance to Form1 constructor, So:
//At From2.Load:
private void Form2_Load(object sender, EventArgs e)
{
this.Hide();//the form2 will hide and show the form 1.
Form1 form1 = new Form1();
form1.ShowDialog();
this.Show();//the form1 is closed so just show this again.
}
From MSDN for Application.Run(Form) method:
"This method adds an event handler to the mainForm parameter for the Closed event. The event handler calls ExitThread to clean up the application."
http://msdn.microsoft.com/en-us/library/ms157902(VS.90).aspx
Basically, when your main form exits, all message pumps are stopped.
I don't know what the forms do in your real-world application but you'll have to work around this behavior. Some ideas - and the correct one probably depends on what you're doing:
If Form1 is some kind of dialog, you could call ShowDialog on it before Application.Run. For example:
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Form1 fm = new Form1();
fm.ShowDialog();
Application.Run(new Form2());
}
When Form1 is closed then Form2 will be opened. The return value of ShowDialog could be used to determine whether to proceed and open Form2, or exit the application.
Another idea might be to call Application.Run twice. Form1 could set a flag indicating whether to open Form2.
Usually in my applications, Form1 is typically some kind of dialog (e.g. a registration form, etc.) and so the first behavior is usually what I do. If the dialog is cancelled then I don't run the application.
Edit: If Form1 may branch out to a number of other forms, you could have it return the form for opening to Main via a field. For example:
Add a public field "Form FormToOpen" to Form1. Set it to null when the form is constructed.
When the button on Form1 is pressed, give FormToOpen a value. For example: "FormToOpen = new Form2()".
Change the Application.Run line as follows:
if (fm.FormToOpen != null) Application.Run(fm.FormToOpen);
At this point it would be trivial for Form1 to have more buttons that open other forms. The main function would not need special knowledge about each form, and the additional forms would not need special knowledge about Form1.
Consider injection of Form2 instance through constructor of Form1, it reduces a class coupling and increases a flexibility, in this way you can safely dispose form1 and keep form2 a live

Passing data between forms

I have two forms. First, Form1 has a group box, some labels and a listbox. I press a button and new Form2 is opened and contains some text. I want to transfer the text in Form2 to the listbox in the Form1.
So far, what I have done is make modifier of listbox to public and then put this code in the button of Form2
Form1 frm = new Form1();
frm.ListBox.items.Add(textBox.Text);
But amazingly, this does not add any value. I thought I was mistaken with the insertion so I made the same procedure. This time, I made a label public and added textbox value to its Text property but it failed.
Any ideas?
Try adding a parameter to the constructor of the second form (in your example, Form1) and passing the value that way. Once InitializeComponent() is called you can then add the parameter to the listbox as a choice.
public Form1(String customItem)
{
InitializeComponent();
this.myListBox.Items.Add(customItem);
}
// In the original form's code:
Form1 frm = new Form1(this.textBox.Text);
Let's assume Form1 calls Form2. Please look at the code:
Form1:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Show();
frm.VisibleChanged += formVisibleChanged;
}
private void formVisibleChanged(object sender, EventArgs e)
{
Form2 frm = (Form2)sender;
if (!frm.Visible)
{
this.listBox1.Items.Add(frm.ReturnText);
frm.Dispose();
}
}
}
Form2:
public partial class Form2 : Form
{
public string ReturnText { get; set; }
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
this.ReturnText = this.textBox1.Text;
this.Visible = false;
}
}
The answer is to declare public property on Form2 and when form gets hidden. Access the same instance and retrieve the value.
Below code working perfect on my machine.
private void button1_Click(object sender, EventArgs e)
{
Form1 f1 = new Form1();
f1.listBox1.Items.Add(textBox1.Text );//ListBox1 : Modifier property made public
f1.ShowDialog();
}
Ok, If you are Calling Sequence is like, Form1->Form2 and Form2 updates the value of Form1 then you have to use ParentForm() or Delegate to update the previous form.
Form1 frm = new Form1();
frm is now a new instance of class Form1.
frm does not refer to the original instance of Form1 that was displayed to the user.
One solution is, when creating the instance of Form2, pass it a reference to your current instance of Form1.
Please avoid the concept of making any public members like you said
>>i have done is make modifier of listbox to public and then in form2 in button code<<
this is not a good practice,on the other hand the good one is in Brad Christie's Post,I hope you got it.
This code will be inside the form containing myListBox probably inside a button click handler.
Form2 frm2 = new Form2();
frm2.ShowDialog();
this.myListBox.Items.Add(frm2.myTextBox.Text);
frm2.Dispose();

Categories

Resources