簡體   English   中英

如何知道所有控件何時加載並顯示?

[英]How do I know when all controls have loaded and displayed?

Windows窗體應用程序中事件的真實順序是什么?

我的意思是,當我將代碼放在Form_Shown事件中時,我希望代碼只在表單顯示之后運行:

動詞(用於對象),顯示,顯示或顯示,顯示。 1.引起或允許被看到... - http://dictionary.reference.com/browse/shown

Form_Shown事件有點誤導。 如果我在該事件中做了一些繁重的事情,似乎代碼在Form 完成顯示之前執行。 假設我在表單上有一個MainMenu ,一個小Toolbar和一個TextBox

我想做一些沉重的事情(現在沒關系線程和工人......),所以我可以使用的最后一個事件我認為是Form_Shown 所以我把沉重的代碼放在那里,但是當表格開始顯示時,我最終等待Toolbar大約5到6秒鍾和顯示的東西(最終發生重型代碼完成之后)

這讓我相信我正在訂閱錯誤的事件。 我根本不想要Form_Shown事件。 我真正需要的是:

Form_WhenALLTheThingsHaveShownEventHandler事件。

那么,當所有的東西(控件)都被完全加載和顯示時,我怎么才能知道?

Shown事件實際上是與引發的初始化相關的最后一個事件。 但請注意,Windows(以及其他平台)上的UI對象的實際渲染 (在屏幕上繪制)將被延遲。 UI對象的創建僅分配所有必要的資源並“使對象的可視區域無效”。 然后平台會調度渲染事件(在非托管Windows中,這是WM_PAINT ,在Winforms API中,這將是Control實例的Paint事件)。

在UI對象的線程可用之前,無法調度呈現事件,如果在Shown事件中有長時間運行的代碼,則會在代碼持續時間內保持UI對象的線程不可用。 即,在代碼完成之前,不會有任何內容被繪制

您還可以使用其他事件來更可靠地檢測事情何時“穩定下來”。 例如, Application.Idle事件告訴您主應用程序線程何時進入空閑狀態。 或者,您可以只訂閱表單的Paint事件。 在任何一種情況下,您都希望使用BeginInvoke()來分派長時間運行的代碼,這樣就不會阻止對這些事件的處理。


現在,所有這一切:你真的不應該在UI線程,期間執行任何長期運行的工作。 使用上述任何一個事件都無法解決潛在的問題; 它只是將問題延遲到UI初始渲染之后。 在您長時間運行的工作正在執行時,UI仍將保持阻塞狀態,坦率地說,用戶可能實際上發現它最好沒有任何UI,而不是那些看似可以與之交互的內容但是他們可以'(即對他們的輸入沒有反應)。

在最新版本的.NET中,有一些非常好的機制可用於將長時間運行的工作轉移到后台線程,以便UI可以保持響應。 請參閱C#中的Taskasync以及await關鍵字 如果您願意,也可以使用舊的BackgroundWorker對象來完成相同的操作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM