我有一个带有一些控件(面板、组框等)的表单,它们都设置了 control.Dock = DockStyle.Top
。基于窗体上 ComboBox 的选定值,只有这些面板中的一些应该同时可见(因为隐藏的面板不适用于所选选项)。对接是为了让UI显得更加简洁。
只要 ComboBox 选择发生变化以及在 Form 的 Shown 事件中,这些 Panel 的 Visible 属性就会发生变化(因为当 Form 第一次显示并且 ComboBox 选择尚未改变时,并非所有 Panel 都应该可见)。
现在的问题是,当我关闭窗体(因为它是模态对话框,它没有被销毁)时,稍后重新打开它并更改 ComboBox 选择面板的显示顺序表格顶部的 已更改。它不会发生,直到表格被关闭一次。我知道停靠控件的显示顺序与父控件的 ControlCollection 中这些控件的顺序相关联。这也决定了控件的 z-Order,因此是问题的标题。
是什么导致控制顺序发生变化以及如何避免?
最佳答案
经过更多调试后我发现重新排序 与句柄创建有关。
第一次打开表单时,所有面板都是可见的(因为我没有
在设计时更改它)并立即创建所有句柄,
在一些被 Form.Shown
事件处理程序隐藏之前。当。。。的时候
窗体关闭,句柄丢失。但是,如果显示表格
第二次,只有面板的 handle
窗体关闭时可见的会立即重新创建。一旦控件变得可见(如 MSDN 点
out) 但显然现在显示控件的顺序很重要
因为控件可以在父级的 ControlCollection 中移动
在句柄创建时。
原来Form第二次显示的时候,之前 显示某个面板(此处为 PanelToBecomeVisible)的控制顺序 是:
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 的位置。
因此,一种解决方案是确保尽早创建所有句柄,即使
如果面板还不可见。这可以通过访问来实现
每个有问题的控件的 Handle
属性,例如,e。例如:
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
关于.net - 如何避免在显示和隐藏控件时更改控件的 z 顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5766386/