Как избежать изменения z-порядка элементов управления при их отображении и скрытии? - PullRequest
3 голосов
/ 23 апреля 2011

У меня есть форма с несколькими элементами управления (панелями, групповыми блоками и т. Д.), На которых установлен control.Dock = DockStyle.Top.Исходя из выбранного значения ComboBox в форме, только некоторые из этих панелей должны быть видны одновременно (поскольку скрытые не применяются для выбранной опции).Стыковка должна сделать пользовательский интерфейс более компактным.

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

Теперь проблема в том, что когда я закрываю форму (поскольку это модальное диалоговое окно, она не уничтожается), открывает ее сновапозже и измените выбор ComboBox, изменился порядок отображения панелей в верхней части формы.Это не происходит, пока форма не была закрыта один раз.Я знаю, что порядок отображения закрепленных элементов управления связан с порядком этих элементов управления в ControlCollection родительского элемента управления.Это также определяет z-порядок элементов управления, отсюда и название вопроса.

Что вызывает изменение порядка элементов управления и как его избежать?

1 Ответ

4 голосов
/ 25 апреля 2011

После дополнительной отладки я обнаружил, что переупорядочение связано с созданием дескриптора.

При первом открытии формы все панели видны (как я не делал изменить это во время разработки) и все ручки будут созданы сразу, прежде чем некоторые из них будут скрыты обработчиком событий Form.Shown. Когда Форма закрыта, ручки потеряны. Тем не менее, если форма отображается во второй раз, только ручки панелей, которые были видны, когда форма была закрыта, воссоздаются немедленно. Каждый дескриптор создается, когда элемент управления становится видимым (как точки MSDN из), но, видимо, теперь важен порядок показа элементов управления потому что элементы управления могут быть перемещены в родительской ControlCollection после создания ручки.

Оказалось, что когда Форма была показана во второй раз, перед показывая определенную панель (здесь PanelToBecomeVisible) порядок управления было:

0    Panel1
1  h InitiallyVisibleButLaterHiddenPanel
2    Panel2
3    PanelToBecomeVisible
4 vh AlwaysVisibleTopMostPanel

, где v означает видимый, а h, что IsHandleCreated имеет значение true. После PanelToBecomeVisible.Visible = True ControlCollection выглядит так это:

0    Panel1
1  h InitiallyVisibleButLaterHiddenPanel
2 vh PanelToBecomeVisible
3    Panel2
4 vh AlwaysVisibleTopMostPanel

И если Panel2 станет видимой позже, она впоследствии поменяется местами позиции с PanelToBecomeVisible.

Таким образом, одним из решений является обеспечение того, чтобы все ручки были созданы даже раньше если панели еще не видны Это может быть достигнуто путем доступа Handle свойство каждого рассматриваемого элемента управления, как это, e. g.:

Private Sub Form_Shown(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Shown
    Dim h As IntPtr
    For Each ctrl As Control In ParentControl.Controls
        h = ctrl.Handle
    Next
End Sub
...