2011-10-17 39 views
2

我正在寫一個WinForms窗口在C#中顯示約12 ListBox和6 ComboBox控制每個有幾百到幾千項。顯示請等待動畫,而用戶界面填充

需要一段時間來填充這些。時間不長 - 只需幾秒鐘,但用戶有興趣看一下,這樣他們就知道程序在等待的時候在後臺工作。

我有一個通用的「Please Wait」動畫無邊界頂部窗口,當這種情況發生時出現,但是我在動畫方面遇到了問題。

對於那些需要一點時間的大部分任務,我解決這個問題的方式如下:

Program.ShowPleaseWait(); // Show top-most animation 

Thread t = new Thread(stuffToDo); // Run stuffToDo() in separate thread 
t.Start(); 

While (t.IsAlive) 
    Application.DoEvents(); // Run message queue, necessary for animation 

Program.HidePleaseWait(); // Hide top-most animation 

,它工作得很好。有時線程中的東西需要調用某些東西,有時會導致動畫中出現小的呃逆,但這通常不是什麼大問題。

但是,通過這種形式,線程中的整個代碼都是UI代碼:填充ListBoxes和ComboBoxes。這意味着所有的東西都必須包含在Invoke塊中,這沒有任何意義,因爲沒有必要讓它首先在單獨的線程中運行。

除了爲這個特殊情況報廢整個工作線程,並在每個循環中每隔幾百次插入一個Application.DoEvents(),我有什麼辦法可以在控件填充時允許工作動畫繼續?

回答

3

只需在第二個線程中運行您的動畫。您可以擁有多個UI線程,但不允許從除初始化線程之外的線程訪問任何UI對象。新線程應接受LoadingAnimationForm(或任何您稱之爲動畫對話框)的實例並致電Application.Run(animForm);當主線程完成填充所有內容時,請致電animForm.Invoke(animForm.Close)。請勿在主線程中調用animForm上的任何其他方法。

+0

工程很棒。感謝那! – Ozzah

+0

事實上,我已經完成並替換了我的代碼的所有實例以使用您的方法。 – Ozzah

+0

@Ozzah:很高興你發現它很有用。 –

1

一種可能的方法是使用空閒時間處理來執行填充代碼。所以你創建一個對話框類來顯示你的動畫。在顯示等待對話框的同時,您掛入空閒時間處理事件。空閒時間處理完成後,您會向對話框發送一條消息,告訴其退出。

唯一的問題是你需要組織你的空閒時間事件,所以它每次調用時只執行一點工作,而不是一次性執行所有工作。如果您一次執行完所有操作,則對話框將無法處理並顯示更新的等待動畫。

+0

一個有趣的建議!這與我正在做的相反 - 使用空閒時間來更新動畫。相反,實施起來有點棘手,因爲在其他地方使用相同的動畫形式。我可以在'ShowPleaseWait'中接受一個泛型函數指針,但將函數分段在空閒時間運行可能會很棘手。 – Ozzah

0

this post摘自:

我要補充這個CodeProject上link

所有你需要的是建立,從工具欄拖動和使用。 LoadingCircle組件沒有任何問題。像魅力一樣工作,你甚至可以定製它!