Nothing happens when I close maximized MDI child form - c#

I have Form1 with 2 radio buttons (rb1 and rb2) and one ordinary button (btn). When I click on btn I should open Form2, as MDI child of Form1 if rb1 is checked, or as ordinary Dialog if rb2 is checked. Also, there can only be one Form2 opened at any moment.
This is my code:
public partial class Form1 : Form
{
Form2 f2;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (f2 != null)
{
MessageBox.Show("Close form!");
return;
}
f2 = new Form2();
if (radioButton1.Checked == true)
{
this.IsMdiContainer = true;
f2.MdiParent = this;
f2.Show();
}
else
{
f2.Show();
}
f2.FormClosed += f2_FormClosed;
}
void f2_FormClosed(object sender, FormClosedEventArgs e)
{
this.IsMdiContainer = false;
f2 = null;
}
}
Everything works as it should except when I maximize Form2 as MDI child and then close it. After that screen stays the same (as I even didn't closed Form2) but I am able to open new Form2, and then Form1's title is "Form1 - [Form2]", and if I repeat the process it would be "Form1 - [Form2] - [Form2]", etc.
I figured out that I my f2_FormClosed method should be
void f2_FormClosed(object sender, FormClosedEventArgs e)
{
f2.Hide(); // <<<<<<<<-----------NEW
this.IsMdiContainer = false;
f2 = null;
}
but I don't know why; Form2 should be closed, I don't know why should I have to hide it?!
Thanks!

I agree with Hans, switching IsMdiContainer at run-time is wonky and is likely to produce other side-effects you haven't seen yet.
Seriously consider a different design for your app.
With that in mind, here's probably the stupidest hack I'll post all day:
public partial class Form1 : Form
{
Form2 f2;
System.Windows.Forms.Timer tmr = new System.Windows.Forms.Timer();
public Form1()
{
InitializeComponent();
tmr.Interval = 100;
tmr.Enabled = false;
tmr.Tick += delegate (object sender, EventArgs e) {
tmr.Stop();
this.IsMdiContainer = false;
};
}
private void button1_Click(object sender, EventArgs e)
{
if (f2 != null)
{
MessageBox.Show("Close form!");
return;
}
f2 = new Form2();
f2.FormClosed += delegate(object sender2, FormClosedEventArgs e2) {
f2 = null;
};
if (radioButton1.Checked == true)
{
this.IsMdiContainer = true;
f2.FormClosed += delegate(object sender3, FormClosedEventArgs e3) {
tmr.Start();
};
f2.MdiParent = this;
}
f2.Show();
}
}
*I originally tried Invoking the call to change IsMdiContainer but that didn't work, so I switched to the Timer. Stupidity that works. Use this solution with caution...

Related

MDI Child form painting issue

Do anyone have any comments about this issue.
This is a MDI Child form displayed inside a MDI Client.And when i overlaps the forms partially on to another form then its no fully repainted. Is this a painting issue.Do anyone have any idea.
Thanks in advance
Sunil
Try this :
Form2 f2;
private void button1_Click(object sender, EventArgs e)
{
if (f2 == null) {
f2 = new Form2();
f2.MdiParent = this;
f2.FormClosed += delegate { f2 = null; };
f2.Show();
}
else {
f2.Activate();
}
}

a problem with bringing form in front

I a form than I can open it also by pressing F1 and clicking so in this code first I check if the form has been opened or not.if was opened I just want to bring it to front. my problem is it wont bring in front by pressing F1 or clicking ToolStripMenuItem if i open it befor.
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
Form2 form2;
form2 = new Form2();
if (e.KeyCode.ToString() == "F1" && Application.OpenForms.OfType<Form2>().Count() <= 0)
// the user pressed the F1 key
form2.Show();
else
{
form2.TopMost = true;
form2.BringToFront();
form2.Focus();
form2.TopMost = false;
}
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
Form2 form2;
form2 = new Form2();
if (Application.OpenForms.OfType<Form2>().Count() <= 0)
form2.Show();
else
{
form2.TopMost = true;
form2.BringToFront();
form2.Focus();
form2.TopMost = false;
}
}
It doesn't work because you forgot to call form2.Show() in the else clause. The code is wrong, you don't want to create a new instance of Form2 if one already exists. Also, there's a bug in Winforms that makes Application.OpenForms lose track of form instances.
Best thing to do is to explicitly keep track of the lifetime of the form with its FormClosed event handler so you don't have to find it back later:
Form2 form2;
private void showForm2() {
if (form2 == null) {
form2 = new Form2();
form2.FormClosed += delegate { form2 = null; };
}
form2.Show();
form2.Focus();
}
Call showForm2 from your event handlers.
Just call form2.Show() and BringToFront. You should declare the `new Form2()' once though.
private Form2 form2;
private void ShowForm2()
{
if (form2 == null)
{
form2 = new Form2();
form2.FormClosed += delegate { form2 = null; };
}
form2.Show();
form2.BringToFront();
}
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
ShowForm2();
}
private void ToolStripMenuItem_Click(object sender, EventArgs e)
{
ShowForm2();
}
From Hans' code, I added the delegate to handle null problem on closing the form and opening it again.

how to prevent opening a form multiple times in c#

i have created an application in which a menustrip is present in which 2 buttons are there, one for ADD, and another for UPDATE & both controls are in a single form, means a button of add & update is there in a single form, whenever i press add button in menustrip update button will be disabled, and when i press update on menustrip the add button will disable. how to do this? i m doing this by show method but that form is opening multiple times using show().
private void addRecordsToolStripMenuItem_Click(object sender, EventArgs e)
{
Form1 f2 = new Form1();
f2.MdiParent = this;
f2.Show();
f2.button1.Enabled = true;
}
private void updateRecordsToolStripMenuItem_Click(object sender, EventArgs e)
{
Form1 f2 = new Form1();
f2.MdiParent = this;
f2.Show();
f2.button2.Enabled = true;
f2.button1.Enabled = false;
}
you simply have to use a single form in this case. try using the singleton approach -
http://hashfactor.wordpress.com/2009/03/31/c-winforms-create-a-single-instance-form/
try using .ShowDialog() instead .Show() and no other form will be able to be clicked on until that one closes.
To do that you'll need to have an instance of that Form outside of those methods that you dismply show if the Form has already been created, or create and show it if it has not (this is the singleton pattern). Here's an example:
Form1 f2 = null;
private void addRecordsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (f2 == null)
{
f2 = new Form1();
f2.MdiParent = this;
f2.button1.Enabled = true;
}
f2.Show();
}
private void updateRecordsToolStripMenuItem_Click(object sender, EventArgs e)
{
if (f2 == null)
{
f2.MdiParent = this;
f2.button2.Enabled = true;
f2.button1.Enabled = false;
}
f2.Show();
}
One question on your disabling of the menu items though, how do you plan on re-enabling them after they have been disabled?
just try to check that form is already opened or not by using its Text Property.. if it is opened just focus on that form other wise show that form as normally
private void button1_Click(object sender, EventArgs e)
{
bool IsOpen = false;
foreach (Form f in Application.OpenForms)
{
if (f.Text == "Form1")
{
IsOpen = true;
f.Focus();
break;
}
}
if (IsOpen == false)
{
Form f1 = new Form1();
f1.Show();
}
}
Try This Guys Its Simple

How to close MDIChild C# VS2010?

Actually Its my first project. While I want to convert my VB.Net2008 to C#2010 I have few clarification pls.
In Form2 Properties I set - IsMDIContainer = True. Then the below code to open my MdiChild and now what is my problem when I click the close button, it's also closing the MDIParent. But I need to close only mdichild... for that I tried as like Vb.Net2008 style by the following codes placed in MDIParent Form2, Its not working. Any right directions ...
private void toolStripButton1_Click(object sender, EventArgs e)
{
Form3 NwMdiChild2 = new Form3;
NwMdiChild2.MdiParent = this;
NwMdiChild2.Dock = System.Windows.Forms.DockStyle.Fill;
NwMdiChild2.Show();
}
private void Form2_FormClosing(object sender, System.Windows.Forms.FormClosingEventArgs e)
{
Form[] MdiChildForms = this.MdiChildren;
int kkk1 = MdiChildForms.Length;
int x = 0;
for (x = 0; x <= MdiChildForms.Length - 1; x += 1)
{
if (MdiChildForms[x].Name == "Form1")
{
kkk1 = kkk1 - 1;
}
MdiChildForms[x].Close();
}
if (kkk1 > 0)
{
// For Not Closing
e.Cancel = true;
}
else
{
// For Closing
e.Cancel = false;
Application.Exit();
}
}
Any Right Directions for Me?
I'm not sure if I understand well what you want to achieve: do you want, when click Parent Form close button, insteed of closing parent form, to close all the child's form? Form2 is your main form (parent MDI container), Form3 is the MDI children, isn't it?
Please try following code and tell if it's what you are asking for:
private void toolStripButton1_Click(object sender, EventArgs e)
{
Form3 NwMdiChild2 = new Form3(); //don't forget ()
NwMdiChild2.MdiParent = this;
NwMdiChild2.Dock = System.Windows.Forms.DockStyle.Fill;
NwMdiChild2.Show();
}
private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
//if no MDI child - this is going to be skipped and norlmal Form2 close takes place
if (this.MdiChildren.Length > 0) //close childrens only when there are some
{
foreach (Form childForm in this.MdiChildren)
childForm.Close();
e.Cancel = true; //cancel Form2 closing
}
}

Altering the view of form only by clicking on the button

Is there any code like, frmBallloon is shown in btnShow click event of the frmBase and again I want to show frmBase if user clicks on the btnShow of the frmBalloon then there is two copy of the frmBase.I want only one copy.Then how can I alter the form view by clicking on the button.
Try this
frmBase button click
Form2 frm2 = new Form2();
this.Visible = false;
frm2.Show(this);
And here frmBalloon Button Click
if (this.Owner != null)
{
this.Visible = false;
this.Owner.Show();
}
You can try something like this
Code for Form1
public Form2 f2;
private void button1_Click(object sender, EventArgs e)
{
if (f2 == null)
{
f2 = new Form2 {f1 = this};
f2.Show();
}
else
f2.Focus();
}
Code for Form2
public Form1 f1;
private void button1_Click(object sender, EventArgs e)
{
if (f1 == null)
{
f1 = new Form1 {f = this};
f1.Show();
}
else
f1.Focus();
}

Categories