2012-08-10 54 views
2

點擊一個按鈕我的代碼是在當前窗體頂部顯示對話框並顯示文本,等待一秒,更改文本然後關閉它:管理C#中的對話框表單#

Form p = new Form(); 
p.ShowDialog(); 

p.Text = "Start."; 
Thread.Sleep(1000); 

p.Text = "Counting."; 
Thread.Sleep(1000); 

p.Text = "End."; 
Thread.Sleep(1000); 

p.Close(); 

但是,一旦它執行p.ShowDialog();它會停止代碼,直到表單p關閉並且它不能按我的意圖工作。我能得到一些關於這方面的指導嗎?不一定是解決方案,但至少可能有一些關鍵字我可以谷歌?

更新:由於我面臨的困難,我正在嘗試訪問業務邏輯,這與問題無關,我推遲提供工作示例。敬請關注和遺憾:)

SOLUTION:我所做的其實是在使用Show()代替ShowDialog()。由於我無法從業務邏輯訪問表單,因此BackgroundWorker派上用場並在其間使用。我不能共享任何代碼或項目結構的佈局,但總而言之,接受答案的主要聲明是解決方案的關鍵:)

+1

你真的應該從表單中,並使用調用 – 2012-08-10 13:38:11

+0

在一個單獨的說明單獨的線程執行的代碼,不使用對話框。他們只是邪惡的。 :)看看你是否可以在你的父母表單的某個空白區域顯示相同的信息。這樣,對用戶和代碼的刺激就不那麼容易了! – Mayank 2012-08-10 13:43:38

+0

您能否就我的回答提供一些反饋?謝謝! – 2012-08-10 16:55:45

回答

3

這就是ShowDialog()的要點。它會創建一個模態表單,並在完成之前不會將控制權返回給調用函數。如果它不需要模態,則使用.Show()。如果它確實需要模態,則將代碼放在「表單加載」方法中以根據需要更新文本。

+0

您將無法將此代碼放在模態窗體中,或者在代碼不是模態的情況下運行此代碼,因爲它會涉及到在UI線程中的睡眠。無論哪種情況,您都需要切換到使用「定時器」或類似的功能。 – Servy 2012-08-10 13:57:00

2

http://msdn.microsoft.com/en-us/library/c7ykbedk.aspx

從鏈接採取以上:

When this method is called, the code following it is not executed until after the dialog box is closed.

如果要形成顯示無論是你想顯示你應該寫代碼的形式裏面本身,做在形式表演事件的事件處理中。

2

正如你所發現的,ShowDialog是一個阻塞方法,直到關閉對話框纔會返回。您的代碼來改變文本和處理延遲需要在對話本身。

但是,值得注意的是你會發現下一個問題:如果你從UI線程中調用Thread.Sleep(1000),你的應用程序將一次無響應1秒。這可能不是你想要的!我建議你看看TimerBackgroundWorker類來處理這個更順利。

1

檢查了這一點:

public partial class Form2 : Form 
{ 
    delegate void SetTextCallback(string text); 
    delegate void CloseFormCallback(); 

    public Form2() 
    { 
     InitializeComponent(); 

     new Thread(DoMagic).Start(); 
    } 

    public void DoMagic() 
    { 
     this.SetText("Start."); 

     Thread.Sleep(1000); 

     this.SetText("Counting."); 
     Thread.Sleep(1000); 

     this.SetText("End"); 

     Thread.Sleep(1000); 

     this.CloseForm(); 
    } 

    private void CloseForm() 
    { 
     if (this.InvokeRequired) 
     { 
      CloseFormCallback c = new CloseFormCallback(CloseForm); 
      this.Invoke(c); 
     } 
     else 
     { 
      this.Close(); 
     } 
    } 

    private void SetText(string text) 
    { 
     if (this.label1.InvokeRequired) 
     { 
      SetTextCallback d = new SetTextCallback(SetText); 
      this.Invoke(d, new object[] { text }); 
     } 
     else 
     { 
      this.label1.Text = text; 
     } 
    } 
} 
+0

這不適用於我,因爲根據數據,我需要從父窗體調用並動態執行此操作。所以我無法把它放在Form2中的線程中。我很確定有一個解決方法,但似乎沒有必要對我想要實現的線程進行線程化,因爲簡單的show而不是showdialog似乎已經解決了這個問題。明天我會更新更多的信息。感謝您的努力,試圖幫助我:) – 2012-08-12 20:36:12

+0

@AndriusNaruševičius我可以修改它從父窗體獲取動態消息。但是,我不明白你將如何顯示錶單並在不使用其他線程的情況下關閉它。任何人,如果你已經設計了一個解決方案,與我們分享=) – 2012-08-13 01:40:51