Stack overflow when opening forms - c#

I am very new to C# so I am sorry if I use wrong terms. Here is my problem. I have 2 forms. and I want If I click the button in Form1, it shows up the Form2 by overlapping the Form1. And now, if I click the button in form2, I want the form1 overlap the form2. But I always get error "stackOverFlowException". Why did i get the error? How to resolve it? I am sorry if my question is not clear. I hope these picture can explain better about my question.
Here is the code for form1.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Form2 frm2 = new Form2();
private void Form1_Load(object sender, EventArgs e)
{
frm2.Show();
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
frm2.Left += 10;
if (frm2.Left >= 750)
{
timer1.Stop();
this.TopMost = false;
frm2.TopMost = true;
timer2.Start();
}
}
private void timer2_Tick(object sender, EventArgs e)
{
frm2.Left -= 10;
if (frm2.Left <= 535)
{
timer2.Stop();
}
}
}
}
and here is the code for form2
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
Form1 frm1 = new Form1();
private void Form2_Load(object sender, EventArgs e)
{
frm1.Show();
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
frm1.Left += 10;
if (frm1.Left >= 750)
{
timer1.Stop();
this.TopMost = false;
frm1.TopMost = true;
timer2.Start();
}
}
private void timer2_Tick(object sender, EventArgs e)
{
frm1.Left -= 10;
if (frm1.Left <= 535)
{
timer2.Stop();
}

You are creating and endless chain of opened forms.
When you first create a Form1 object with new Form1(), the initialization code inside this form
Form2 frm2 = new Form2();
... is called. This in turn triggers the initialization code of Form2, which is
Form1 frm1 = new Form1();
This creates a new instance of this form (now you have two Form1 instances) and calls Form2 frm2 = new Form2(); again in this new instance (now you have two Form2 instances). This goes on until thousands of form objects have been created and the stack overflows.
What can you do about it?
In Form2 add a parameter to the constructor that allows you to pass a reference to the first form
private readonly Form1 _frm1;
public Form2 (Form1 frm1)
{
InitializeComponent();
_frm1 = frm1;
}
In Form1 do this
private Form2 _frm2;
private void Form1_Load(object sender, EventArgs e)
(
_frm2 = new Form2(this);
)
I.e. Form2 never creates a Form1. Instead, it gets a reference to the already opened form.
How do you bring a form to front?
The TopMost property controls the behavior of a form when it is opened. Instead, use
_frm1.BringToFront();
to change the z-order afterwards.

Related

How to call Form 1's method from Form2 without static and new class();?

How to call Form 1's method when Form is resized without static and new class(); like below codes. because more than one new class(); The "System.StackOverflowException" issue is causing when the code is used. it does not take the values it saves in the class due static.
Form1 class code:
Form2 frm2 = new Form2();
public void ResizePicture(int Height, int Width)
{
frm2.pictureBox1.Height = Height;
frm2.pictureBox1.Width = Width;
}
private void button1_Click(object sender, EventArgs e)
{
frm2.pictureBox1.Image = Image.FromFile(#"C:\Users\Omer\Desktop\screenshot.png");
frm2.Show();
}
Form2 class code:
private void Form2_Resize(object sender, EventArgs e)
{
ResizePicture(this.Height, this.Width);
}
You can subscribe to the Resize event of the other form
In Form1:
private readonly Form2 frm2;
private Form1()
{
InitializeComponent();
frm2 = new Form2();
frm2.Resize += Frm2_Resize;
}
private void Frm2_Resize(object sender, EventArgs e)
{
...
}
This code only creates a Form2 once in the constructor of Form1. Now the Resize event handler of Form2 is in Form1.
Another possibility is to pass a reference of the first form to the second one
In Form2:
private readonly Form1 frm1;
private Form2(Form1 frm1)
{
InitializeComponent();
this.frm1 = frm1;
}
private void Form2_Resize(object sender, EventArgs e)
{
frm1.ResizePicture(this.Height, this.Width);
// Note: `ResizePicture` must be public but not static!
}
In Form 1
frm2 = new Form2(this); // Pass a reference of Form1 to Form2.
Another one, passing Form1 via Show() itself:
private void button1_Click(object sender, EventArgs e)
{
frm2.pictureBox1.Image = Image.FromFile(#"C:\Users\Omer\Desktop\screenshot.png");
frm2.Show(this); // <-- passing Form1 here!
}
In Form2, you cast .Owner back to Form1:
private void Form2_Resize(object sender, EventArgs e)
{
Form1 f1 = (Form1)this.Owner;
f1.ResizePicture(this.Height, this.Width);
}

Change the form.text programmatically with a button of other form

I can't update the first form of my application. when it opens it loads all the elements, then through a button I open a second form and from that, with a button I should reload all the controls of the first form including form1.text but this does not happen. despite the marker I saw that the text variable is updated correctly, however on a graphic level it does not change.
form1:
public partial class Form1 : Form
{
public string mail { get; private set; }
public Form1()
{
InitializeComponent();
}
public void Form1_Load(object sender, EventArgs e)
{
this.Text = "table - Last Update: " + DateTime.Now.ToString();
...some other code...
}
public void updateform()
{
this.Controls.Clear();
InitializeComponent();
Form1_Load(null, null);
this.Refresh();
}
private void button1_Click(object sender, EventArgs e)
{
mail = lbl1.Text;
Form2 form2 = new Form2(mail);
form2.Show();
}
}
form2:
public partial class Form2 : Form
{
public Form2(String stringa)
{
InitializeComponent();
email = stringa;
}
private void button1_Click(object sender, EventArgs e)
{
Form1 f1 = new Form1();
f1.updateform();
this.Close();
}
You can pass a reference to Form1, into Form2 using the Show() command. The reference can be accessed using the .Owner property.
In Form1:
private void button1_Click(object sender, EventArgs e)
{
mail = lbl1.Text;
Form2 form2 = new Form2(mail);
form2.Show(this); // <-- pass reference to Form1
}
In Form2:
private void button1_Click(object sender, EventArgs e)
{
Form1 f1 = this.Owner as Form1; // <-- attempt to convert .Owner to Form1
if (f1 != null)
{
f1.updateform();
}
this.Close();
}

How can you hide a button from another form

I have a C# project that has 2 forms. The first has 3 buttons. I need to be able from the second form to hide 2 (button1 and button2 )buttons with a checkbox, and I don't know how to call the buttons from the first form.
this is form1
namespace test1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button3_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Show();
}
private void button1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
}
}
and this is Form2
namespace test1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
checkBox1.Checked = Properties.Settings.Default.checkB;
if (checkBox1.CheckState == CheckState.Checked)
{
?????????
}
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
Properties.Settings.Default.checkB = checkBox1.Checked;
Properties.Settings.Default.Save();
}
}
}
Another option is to pass the form as the "owner" in the Show() command:
private void button3_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Show(this); // pass Form1 reference in to our instance of Form2
}
In Form2, cast the Owner property back to Form1 so you can access it (assuming you've changed the modifiers property of the buttons to public as already suggested):
private void Form2_Load(object sender, EventArgs e)
{
checkBox1.Checked = Properties.Settings.Default.checkB;
if (checkBox1.CheckState == CheckState.Checked)
{
Form1 f1 = (Form1)this.Owner;
f1.button1.Visible = false; // or whatever your buttons are called
}
}
This is almost exactly what I had posted previously...you need to change the Modifiers property of the buttons so they are public and can be seen from Form2.
this is the final version that works in my case thanks to those who answered my question and helped me to get this answer
Form1
namespace test1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Form2 frm = new Form2();
frm.checkBox1.Checked = Properties.Settings.Default.checkB;
if (frm.checkBox1.CheckState == CheckState.Checked)
{
button1.Visible = false;
}
}
private void button3_Click(object sender, EventArgs e)
{
Form2 frm = new Form2();
frm.Show(this);
}
private void button1_Click(object sender, EventArgs e)
{
}
private void button2_Click(object sender, EventArgs e)
{
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
}
}
}
Form2
namespace test1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void Form2_Load(object sender, EventArgs e)
{
checkBox1.Checked = Properties.Settings.Default.checkB;
if (checkBox1.CheckState == CheckState.Checked)
{
Form1 f1 = (Form1)this.Owner;
f1.button1.Visible = false;
}
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
Properties.Settings.Default.checkB = checkBox1.Checked;
Properties.Settings.Default.Save();
}
}
}
The buttons and checkBox are set to Modifiers - Public
you need to make the buttons on the first form public and then you can access them once you create a instance of the first form you will need to pass that form to the second form.
Might want to look into building an event that fires from one form and gets handled by the other form to disable the button.

Activate another Form

From Form1 I've been opening Form2. If I then click on a button or whatever in Form1, I want Form2 to be activated. Something like
Form2.Activate();
But that just gives me errors.
This is my code right now:
private void button1_Click(object sender, EventArgs e) // first I click here
{
Form2 f2 = new Form2();
f2.Show();
}
private void button2_Click(object sender, EventArgs e) // then here, to activate it
{
Form2 f2 = new Form2();
f2.Activate();
}
You're having that error because Activate method should be called from an instance of the Form2 class not the Form2 class its self, Activate() is not a Static method, You have to instantiate the Form2 class first, this event handler is for a button click on the first Form
private void button1_Click(object sender, EventArgs e)
{
Form2 form2 = new Form2();
form2.Show();
}
this was to show the form, to activate it and make it the main one showed to you, you can than call the Activate() method to that instance, like
form2.Show();
form2.Activate();
I believe you need to create an instance of a class in order to access instance methods. Basically, the instance is created via a constructor call, like this:
Form2 form = new Form2();
However, the method to show newly created form is this one:
form2.Show();
Move the Form2 reference out to Class level so it can be accessed from both button1 and button2.
Something like...
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
Form2 f2 = null;
private void button1_Click(object sender, EventArgs e) // first I click here
{
if (f2 == null || f2.IsDisposed)
{
f2 = new Form2();
f2.Show();
}
else
{
ActivateForm2();
}
}
private void button2_Click(object sender, EventArgs e) // then here, to activate it
{
ActivateForm2();
}
private void ActivateForm2()
{
if (f2 != null && !f2.IsDisposed)
{
if (f2.WindowState == FormWindowState.Minimized)
{
f2.WindowState = FormWindowState.Normal;
}
f2.Activate();
}
}
}

How to show another form after playing an SWF file in C#

I have a form that contains a Shockwave Flash object. I want that after playing the file or in the middle of it by pressing a key another form is shown. What should I do? Should I use an event?
Here's the code:
private void Form1_Load(object sender, EventArgs e)
{
axShockwaveFlash1.Movie = "c:/intro.swf";
axShockwaveFlash1.Forward();
axShockwaveFlash1.Play();
Form2 form2 = new Form2();
form2.Show();
}
And in Form2:
private void Form2_Load(object sender, EventArgs e)
{
Form1 form1 = new Form1();
form1.Close();
}
When I debug both forms are shown but I just want Form2.
You can pass the Form1 instance to the Form2 constructor, and close it there, like:
public Form2(Form1 form1)
{
InitializeComponents();
form1.Hide();//hide the control from the user, or close it if it not the main form..
}
Or if you want it to close the form1 instance when a button click then:
private Form1 _form1 = null;
public Form2(Form1 form1)
{
InitializeComponents();
_form1 = form1;
}
private void button1_Click(object sender, EventArgs e)
{
if (_form1 != null)
{
_form1.Hide();
}
}
Initialize the form2 in form1:
axShockwaveFlash1.Movie = "c:/intro.swf";
axShockwaveFlash1.Forward();
axShockwaveFlash1.Play();
Form2 form2 = new Form2(this);//"this here is the form1 instance itself"
form2.Show();
you can also use timer to check weather the movie is playing or not,if not then open new form which is form2
private void flash_Load(object sender, EventArgs e)
{
axShockwaveFlash1.Movie = #"C:\Users\Adil M\Documents\Visual Studio 2012\Projects\TProject\a.swf";
int a = axShockwaveFlash1.MovieData.Length;
timer1.Start();
}
now code on timer event
private void timer1_Tick(object sender, EventArgs e)
{
if (!axShockwaveFlash1.IsPlaying())
{
Fome2 fobj = new Form2();
this.Hide();
timer1.stop();
fobj.show();
}
else if(axShockwaveFlash1.IsPlaying())
{
}
}
this code is working for you only when your movie is complete or for any key you can also do it in timer
thanx

Categories