Почему скрытие и отображение дочернего элемента mdi перемещает дочерний элемент?

У меня есть очень простой mdiparent из коробки, в котором есть несколько mdichildren и пункт меню. Каждая кнопка в пункте меню скрывает все формы, а затем показывает форму, соответствующую этой кнопке.

Когда я делаю это так:

        //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;

Переключение форм приводит к тому, что новая открытая форма располагается немного ниже и правее старой формы, но щелчок по пункту меню для текущей отображаемой формы ничего не делает (как и ожидалось).

Но, когда я делаю это:

        //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;

Даже щелчок по элементу меню для видимой в данный момент формы приводит к его смещению в нижний правый угол, как при открытии новой формы. Это почему?

Редактировать:

Я также заметил, что при центрировании формы, а затем ее отображении (чтобы вы не рискуете, что кто-то увидит ее прямо перед тем, как она будет перемещена), установка для параметра visible значения true полностью сбрасывает любое центрирование, которое я сделал.


person Lawtonfogle    schedule 19.12.2014    source источник
comment
Если вы хотите, чтобы отображалась только одна форма, зачем вообще использовать MDI? Вы можете использовать TabConrol и трюк, опубликованный Хансом Пассантом, показанный здесь.   -  person Idle_Mind    schedule 19.12.2014
comment
Это внутреннее очень простое приложение, и я просто играл с MDI. Я просто максимизирую их с самого начала, и, похоже, это работает. Вероятно, это не лучший способ сделать это, но код прост, похоже, что сложность не будет ужасно увеличиваться, и я узнаю новые вещи. Если бы это было для клиентов, я бы определенно тратил больше времени на то, чтобы убедиться, что все делаю правильно.   -  person Lawtonfogle    schedule 19.12.2014


Ответы (1)


Это вызвано неясной деталью реализации в Winforms. Собственная поддержка MDI, встроенная в Windows, не поддерживает скрытие дочерних окон. Winforms обходит это ограничение, уничтожая дочернее окно, когда вы устанавливаете для его свойства Visible значение false. И воссоздать его, когда вы вернете его в значение true.

Это может иметь различные побочные эффекты, состояние собственного окна, конечно, теряется, когда это происходит. Winforms имеет довольно достойную поддержку для повторного восстановления окна из его свойств. Но одна вещь, которую он не делает, — это воссоздание окна в том же месте. Таким образом, вы увидите, что оно воссоздается в том же месте, что и новые дочерние окна MDI, в шахматном порядке по сравнению с предыдущим окном. Было ли это недосмотром или преднамеренным, мне не совсем ясно, вероятность 95% для последнего.

В противном случае просто обойти, вы можете назначить свойство Location самостоятельно, чтобы вернуть его туда, где он был:

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

Или просто установите для StartPosition дочерней формы MDI значение Manual.

person Hans Passant    schedule 19.12.2014
comment
Я пытался вручную установить местоположение, но в нескольких случаях он на мгновение мерцал. Оно перестраивается по умолчанию (немного ниже и правее предыдущего окна) перед перемещением в новое место. Конечно, я вижу это менее чем в 50% случаев, но все же заметно. При этом я не спрашивал, как это исправить, а только почему это происходит, и вы объяснили это, поэтому я дам вам ответ. - person Lawtonfogle; 19.12.2014