2008-10-13 43 views
3

後來我遇到了一種情況,我們需要向用戶顯示消息框以獲取通知,但我們無法使用MessageBox.Show,因爲它阻止了GUI線程(所以在對話框處於活動狀態時屏幕上沒有任何內容會更新)。有關替代方案的任何建議?對不阻止GUI線程的MessageBox.Show替換的建議?

[我在當時編碼的替代品,但我不喜歡它。如果沒有更好的出現,我會張貼它作爲答案]

編輯:對話框必須浮在主窗口頂部;我不在乎它是否出現在任務欄中。在特定情況下,可能會同時激活多個對話框。

附錄:我的解決方案是提供OK和CANCEL按鈕以發出Completed和Canceled事件的基本形式;確定爲子類覆蓋調用了一個虛擬的ValidateData。調用表單使用屬性來避免每次都重新創建表單(表單只是隱藏而不是關閉),並保存活動表單的字典以防止同一表單被激活多次。這看起來像一個模態形式,一次支持多個彈出窗體,但不會捆綁主GUI線程。

+0

我不明白downvoting這樣直接的問題... – 2009-02-24 20:11:42

回答

4

我同意rslite和Mitchel Sellers。創建一個非模態窗體來顯示所需的信息是最好的路線。如果您有多條消息,則可能需要考慮將它們放入ListBox中,並讓用戶雙擊它們以獲取需要顯示的完整信息。

+0

這基本上是我不得不做的;非模態形式不是很有趣,但工作正常 - 它看起來模態,但實際上不是;-) – 2008-10-17 05:55:11

1

我會解決這個問題,通過使用非模式對話框或根據具體要求可能一些工具提示。

1

如果你不希望它阻塞,我只是創建自己的簡單窗體來做顯示。這就是我在需要非阻塞解決方案之前爲客戶完成的項目。但請記住,如果您將它視爲非阻塞,那麼用戶可以獲得倍數並且如果它們確實是「您必須採取行動」類型的項目,就會被淹沒。

-1

如果您希望MessageBox外觀只顯示在後臺線程中。

ThreadPool.QueueUserWorkItem((state) => 
    { 
     MessageBox.Show("Your message"); 
    }); 

(代碼未測試)

+0

我懷疑這將工作,因爲MessageBox依賴於窗體和形式只能從主線程訪問。即使它起作用,您也不應該通過在後臺線程上調用SWF來搞砸它。 – OregonGhost 2008-10-13 20:43:03

4

我建議用非模態的方法去,就像有人說的,但多了幾分特殊:

  • 如果你只是想通知你可能會嘗試一個氣球提示(TNA或您自己的),或者是一個類似於Outlook郵件通知的窗口,或者通知許多即時通訊工具,如Trillian顯示。
  • 如果您只是想讓用戶有機會採取行動,請使用非模態形式,但請記住,只需將其單擊即可。
  • 如果用戶必須對您的信息採取行動,您應該選擇模態。請注意,所有者窗口仍將被繪製,並且您可以刷新GUI - 畢竟,模式對話框具有消息泵,否則它將無法工作。我最近做了類似的事情,我們有一個後臺工作程序線程池,它可以繼續執行任何用於GUI刷新的動作和觸發事件,以及仍然獲取其消息的模態等待對話框。所有者窗口確實按預期進行了後臺操作更新。
1

感謝大家誰貢獻的建議,看來我的解決辦法是基本正確;-)

我的解決方案是,提供確定和取消按鈕發出完成和已取消事件基本形式;確定爲子類覆蓋調用了一個虛擬的ValidateData。調用表單使用屬性來避免每次都重新創建表單(表單只是隱藏而不是關閉),並保存活動表單的字典以防止同一表單被激活多次。這看起來像一個模態形式,一次支持多個彈出窗體,但不會捆綁主GUI線程。

2

如何在應用程序中添加NotifyIcon並顯示balloon tip。不好的一面是,通知會在很短的時間後消失,但如果用戶不需要採取措施,那麼這對用戶來說可能是最好的。