tags:

views:

25

answers:

1

I have a main form 'MainForm' with IsMdiContainer = true

I have one or more dynamically created child forms where I set MdiParent = MainForm

Now what I want to do is to be able to detach these child forms by setting MdiParent = null, but with maintaining the exact same screen location.

I've tried to use ChildForm.PointToScreen(ChildForm.Location), but that gives me the screen location relative to the client area of the form.

EDIT

PointToScreen() on the form itself gives me almost the correct location, except that it gives the screen location of 0,0 inside the form, while .Location refers to the outer edge of the form.

+2  A: 

You have to use the parent's mdi client window's PointToScreen() method:

    private void button1_Click(object sender, EventArgs e) {
        if (this.MdiParent != null) {
            MdiClient client = null;
            foreach (Control ctl in this.MdiParent.Controls) {
                if (ctl is MdiClient) { client = ctl as MdiClient; break; }
            }
            this.WindowState = FormWindowState.Normal;
            Point loc = client.PointToScreen(this.Location);
            this.MdiParent = null;
            this.Location = loc;
        }
    }

You cannot avoid the slight offset you get on Aero, nor the flicker.

Hans Passant
This doesn't work as I have other items docked in 'MainForm'. The code above will position the form with the same relative distance to 'MainForm' as previously to the MdiClient area.
thomask
You'll have to find the MdiClient window so you can use its PointToScreen method. Find it by iterating the parent's Controls collection, test with "is MdiClient". Or just adjust the position.
Hans Passant
Posted snippet updated.
Hans Passant
That turned out to work perfectly. The only thing left is to reposition the form inside the MdiClient properly, which seems to be impossible. The form is either cascaded or stuck at 0,0 :)
thomask