1

I have a very basic out the box mdiparent which has a number of mdichildren and a menu item. Each button on the menu item hides all the forms and then shows the one respective to that button.

When I do it this way:

        //dontHide is the Form we want to show.
        for(int i = 0; i < this.MdiChildren.Length; i++)
        {
            if (this.MdiChildren[i] != dontHide)
            {
                this.MdiChildren[i].Visible = false;
            }
        }
        dontHide.Visible = true;

Switching forms causes the new form opened to be positioned bit lower and to the right of the old form, but clicking the menu item for the currently displayed form does nothing (as expected).

But, when I do this:

        //dontHide is the Form we want to show.
        for(int i = 0; i < this.MdiChildren.Length; i++)
        {
            this.MdiChildren[i].Visible = false;
        } 
        dontHide.Visible = true;

Even clicking the menu item for the currently visible form causes it to shift to the lower right, same as opening a new form. Why is that?

Edit:

I've also noticed when centering the form and then displaying it (so you don't risk having someone glimpse it right before it is moved), setting visible to true completely resets any centering I've done.

Lawtonfogle
  • 974
  • 4
  • 17
  • 32
  • If you only want **one** Form shown at a time, why use MDI at all? You could use a TabConrol and the trick posted by Hans Passant shown [here](http://stackoverflow.com/a/6954785/2330053). – Idle_Mind Dec 19 '14 at 16:39
  • This is an internal really simple app and I was just playing around with MDI. I'm just maximizing them from the get go and it seems to be working. Probably not the best way to do this, but the code is simple, it looks like the complexity won't scalre horribly, and I'm learning new things. If this was for customers I would definitely spend more time ensuring I was doing things the right way. – Lawtonfogle Dec 19 '14 at 18:40

1 Answers1

3

This is caused by an obscure implementation detail in Winforms. The native MDI support built into Windows does not support hiding child windows. Winforms works around this restriction by destroying the child window when you set its Visible property to false. And re-creating it when you set it back to true.

This can have various side-effects, the state of the native window is lost when this happens of course. Winforms has fairly decent support for restoring the window again from its properties. But one thing it doesn't do is recreating the window in the same location. So you'll see it getting recreated in the location that new MDI child windows get, staggered from the previous window. Whether that was an oversight or intentional isn't that clear to me, 95% odds for the latter.

Otherwise simple to work around, you can assign the Location property yourself to get it back where it was:

  var loc = dontHide.Location;        
  dontHide.Visible = true;
  dontHide.Location = loc;

Or just set the MDI child form's StartPosition to Manual.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • I've tried manually setting location but in a few casts it causes it to flicker momentarily. It gets rebuilt in the default (slightly lower and to the right of the previous window) before being moved to the new location. Granted, I see it less than 50% of the time, but it is still noticeable. That being said, I didn't ask how to fix it, only why it was happening, and you explained that, so I'll give you the answer. – Lawtonfogle Dec 19 '14 at 18:38