在显示和隐藏控件时,如何避免控件的z顺序发生变化?

时间:2011-04-23 19:29:05

标签: .net winforms show-hide visible z-order

我有一个表格,上面有一些控件(面板,组合框等),它们都设置了control.Dock = DockStyle.Top。根据表单上ComboBox的选定值,只有部分面板应该同时可见(因为隐藏的面板不适用于所选选项)。对接是为了使UI看起来更紧凑。

每当ComboBox选择更改时以及Form的Shown事件时,这些面板的Visible属性都会更改(因为当首次显示Form并且ComboBox选择尚未更改时,并非所有Panel都可见)。< / p>

现在,问题是,当我关闭Form时(因为它是一个模态对话框,它没有被销毁),稍后重新打开它并更改ComboBox选择面板的显示顺序在表格的顶部已经改变。直到表格关闭一次才会发生。我知道停靠控件的显示顺序链接到父控件的ControlCollection中这些控件的顺序。这也决定了控件的z顺序,因此也就是问题的标题。

是什么导致控制命令改变以及如何避免它?

1 个答案:

答案 0 :(得分:4)

经过多次调试后我发现了重新排序 与句柄创建有关。

首次打开表单时,所有面板都可见(因为我没有 在设计时更改它,并立即创建所有句柄, 在某些事件被Form.Shown事件处理程序隐藏之前。当。。。的时候 表格已关闭,句柄丢失。但是,如果显示表格 第二次,只有面板的手柄 窗体关闭时可见,立即重新创建。一旦控件变为可见(如MSDN点),就会创建每个句柄 out)但显然现在显示控件的顺序很重要 因为可以在父级的ControlCollection中移动控件 在创建句柄时。

事实证明,当表格第二次出现之前 显示某个Panel(此处为PanelToBecomeVisible)的Control命令 是:

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

其中v表示可见,而h表示IsHandleCreated为真。后 PanelToBecomeVisible.Visible = True ControlCollection看起来像 这样:

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

如果Panel2稍后可见,它将随后进行交换 PanelToBecomeVisible的职位。

因此,一种解决方案是确保所有句柄都是尽早创建的 如果小组尚未显示。这可以通过访问来实现 像这样的每个Control的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