3

すべてがcontrol.Dock = DockStyle.Top設定されているいくつかのコントロール (パネル、グループ ボックスなど) を含むフォームがあります。フォームの ComboBox の選択された値に基づいて、これらのパネルの一部のみが同時に表示されます (非表示のパネルは選択されたオプションには適用されないため)。ドッキングは、UI をよりコンパクトに見せるためのものです。

これらのパネルの Visible プロパティは、ComboBox の選択が変更され、フォームの Shown イベントが発生するたびに変更されます (フォームが初めて表示され、ComboBox の選択がまだ変更されていないときに、すべてのパネルが表示されるわけではないため)。

さて、問題は、フォームを閉じると (モーダル ダイアログであるため、破棄されません)、後で再度開き、コンボ ボックスの選択を変更すると、フォームの上部にあるパネルの表示順序が変更されることです。フォームが一度閉じられるまで発生しません。ドッキングされたコントロールの表示順序は、親コントロールの ControlCollection 内のこれらのコントロールの順序にリンクされていることを知っています。これにより、コントロールの z オーダーも決定されるため、質問のタイトルになります。

コントロールの順序が変更される原因とそれを回避する方法は?

4

1 に答える 1

5

さらにデバッグした後、並べ替えがハンドルの作成に関連していることがわかりました。

フォームを最初に開いたとき、すべてのパネルが表示され(設計時に変更しなかったため)、すべてのハンドルがすぐに作成され、一部はForm.Shownイベントハンドラーによって非表示になります。フォームを閉じると、ハンドルが失われます。ただし、フォームが2回目に表示された場合は、フォームを閉じたときに表示されていたパネルのハンドルのみがすぐに再作成されます。コントロールが表示されると(MSDNが指摘するように)各ハンドルが作成されますが、ハンドルの作成時にコントロールを親のControlCollectionで移動できるため、コントロールを表示する順序が重要になっているようです。

フォームが2回目に表示されたとき、特定のパネル(ここではPanelToBecomeVisible)を表示する前に、制御順序は次のようになりました。

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

ここで、vは表示を意味し、hはIsHandleCreatedがtrueであることを意味します。PanelToBecomeVisible.Visible = TrueControlCollectionが次のようになった後 :

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

また、Panel2が後で表示されるようになると、その後、PanelToBecomeVisibleと位置が入れ替わります。

したがって、1つの解決策は、パネルがまだ表示されていない場合でも、すべてのハンドルが早期に作成されるようにすることです。Handleこれは、次のように問題のすべてのコントロールのプロパティにアクセスすることで実現できます。

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
于 2011-04-25T09:40:57.293 に答える