简体   繁体   中英

Nothing happens when I close maximized MDI child form

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...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM