2011-03-18 49 views
15

點擊button1放置在form1之後,程序正在檢查新版本是否可用(通過互聯網),但是在新線程中執行此操作(而不是在檢查期間凍結表單)。
當找到新版本時,會顯示相應的MessageBox,但它沒有父項(因爲它是從線程調用的,而不是直接從form1中調用)。從Form1作爲父母的異步線程調用MessageBox

如何使MessageBox顯示爲form1作爲父項?

回答

26
this.Invoke(new Action(() => { MessageBox.Show(this, "text"); })); 

這將切換到主線程並顯示帶有form1父項的MessageBox。

+0

這給了我很多的編譯錯誤(即錯誤關鍵詞'this'在靜態屬性,靜態方法或靜態字段初始值設定項中無效) – daftu 2011-03-18 08:29:17

+0

取而代之的是'this'使用form1的實例 – Stecya 2011-03-18 08:32:10

+0

雖然您在這裏如何獲得DialogResult? Invoke返回一個對象,它是空的。 – 2013-12-16 16:04:25

3
if (Form1.InvokeRequired) { 
      Form1.Invoke((Action)delegate{MessageBox.Show(Form1,"Hello");}); 
     } 
1

嘗試使用backgroundworker

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    //Helper thread: Long during task 
} 

private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    //We're in the main thread: Show your messagebox 
} 
9

雖然選擇的答案提供了一種從異步線程顯示MessageBox的一個很好的方式,它不處理,你想要從該特定MessageBoxDialogResult正在顯示的情況。

如果您想要從Form頂部顯示的被調用MessageBox返回DialogResult。然後您需要使用Func代表,而不是Action代表。

Action代表總是返回void,而Func具有返回值。

這裏是一個小方法,我設計來處理這種特殊的情況:

private DialogResult BackgroundThreadMessageBox(IWin32Window owner, string text) 
{ 
    if (this.InvokeRequired) 
    { 
     return (DialogResult) this.Invoke(new Func<DialogResult>(
          () => { return MessageBox.Show(owner, text); })); 
    } 
    else 
    { 
     return MessageBox.Show(owner, text); 
    } 
} 

雖然這通常不認爲是最佳做法或設計會在緊要關頭。

+0

出於好奇,更好的實踐/設計會是什麼? – 2017-03-07 15:11:52

0

在我的情況,我在另一個類和有一個TextBox的參考,所以我用下面的代碼:

_txtResultado.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(delegate() 
{ 
    MessageBox.Show("My message!"); 
}));