2011-04-23 49 views
3

我已經有一個表格,其上有一些控件(面板,組框等),它們都有control.Dock = DockStyle.Top設置。根據Form上ComboBox的選定值,這些面板中的某些應該同時可見(因爲隱藏的不適用於所選的選項)。對接旨在使界面看起來更加緊湊。如何避免在顯示和隱藏控件時改變控件的z順序?

只要ComboBox選擇發生更改並顯示在窗體的顯示事件中(因爲在第一次顯示窗體並且組合框選擇尚未更改時不應顯示所有面板),這些面板的可見屬性會被更改。

現在的問題是,當我關閉窗體(因爲它是一個模式對話框,它不被破壞),重新打開它後和更改組合框選擇在頂部面板的顯示順序表格已經改變。直到表單關閉一次纔會發生。我知道停靠控件的顯示順序與父控件的ControlCollection中這些控件的順序相關聯。這也決定了控件的z順序,因此問題的標題。

是什麼原因導致控制訂單發生變化以及如何避免?

+0

從描述中不可想像。將帶有此問題的小型repro項目發佈到文件共享服務或粘貼bin。 – 2011-04-23 20:04:13

+0

@HansPassant呃,其實我在這期間找到了答案,但是我還沒有發佈(因爲我的聲望得分太低)。你的意思是我描述這個問題很糟糕,應該改寫它,或者你只是需要一些代碼來自己挖掘它? – JayK 2011-04-23 20:14:07

+0

我認爲答案可能對未來的其他人有幫助......但如果您不這麼認爲,請再次告訴我,我會將其刪除。 – JayK 2011-04-23 20:21:52

回答

3

經過更多調試後,我發現重新排序 與Handle創建有關。

當窗體第一次打開,所有的面板是可見的(因爲我沒有 變化,在設計時),所有的句柄,立即創建, 之前有一些由Form.Shown事件處理程序隱藏。當表格關閉時,手柄將丟失。但是,如果窗體第二次顯示爲 ,則只有窗體關閉時可見的面板的手柄纔會立即重新創建。一旦控件變得可見,就會創建每個句柄(因爲MSDN指向 ),但顯然現在顯示控件的順序很重要,因爲可以在創建句柄時將控件移動到父控件的ControlCollection中 。

原來,當窗體被示出在第二時間, 之前呈現一定的面板(這裏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屬性來解決。 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