Jay*_*ayK 3 .net z-order visible show-hide winforms
我有一个表单,上面有一些控件(面板、分组框等),所有这些都已control.Dock = DockStyle.Top
设置。根据窗体上组合框的选定值,只有其中一些面板应该同时可见(因为隐藏的面板不适用于选定的选项)。对接是为了让UI看起来更紧凑。
每当 ComboBox 选择更改时以及在 Form 的 Shown 事件中,这些面板的 Visible 属性都会更改(因为当首次显示 Form 并且 ComboBox 选择尚未更改时,并非所有面板都应该可见)。
现在,问题是,当我关闭窗体时(因为它是一个模式对话框,它没有被破坏),稍后重新打开它并更改组合框选择,窗体顶部面板的显示顺序已更改。直到表单关闭一次后才会发生这种情况。我知道停靠控件的显示顺序与父控件的 ControlCollection 中这些控件的顺序相关联。这也决定了控件的 z 顺序,因此决定了问题的标题。
是什么导致控制顺序发生变化以及如何避免它?
经过更多调试后,我发现重新排序与 Handle 创建有关。
当表单第一次打开时,所有面板都是可见的(因为我在设计时没有改变它)并且在一些被Form.Shown
事件处理程序隐藏之前立即创建所有句柄。当窗体关闭时,句柄丢失。但是,如果第二次显示窗体,则只会立即重新创建窗体关闭时可见的面板的句柄。一旦控件变得可见(正如 MSDN 指出的那样),每个句柄都会被创建,但显然现在显示控件的顺序很重要,因为控件可以在创建句柄时在父级的 ControlCollection 中移动。
原来,当第二次显示表单时,在显示某个面板(这里是 PanelToBecomeVisible)之前,控制顺序是:
0 Panel1
1 h InitiallyVisibleButLaterHiddenPanel
2 Panel2
3 PanelToBecomeVisible
4 vh AlwaysVisibleTopMostPanel
Run Code Online (Sandbox Code Playgroud)
其中 v 表示可见,h 表示 IsHandleCreated 为真。在
PanelToBecomeVisible.Visible = True
ControlCollection 之后看起来像这样:
0 Panel1
1 h InitiallyVisibleButLaterHiddenPanel
2 vh PanelToBecomeVisible
3 Panel2
4 vh AlwaysVisibleTopMostPanel
Run Code Online (Sandbox Code Playgroud)
如果 Panel2 稍后变为可见,它将随后与 PanelToBecomeVisible 交换位置。
因此,一种解决方案是确保尽早创建所有句柄,即使面板尚不可见。这可以通过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
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
743 次 |
最近记录: |