2010-07-06 56 views
0

我在窗體應用程序中有一個窗體,我想要在主窗體頂部顯示,關閉它,然後立即使用MessageBox.Show()顯示一個對話框。但是,當消息框顯示時,第一種形式仍然顯示,並且直到我在消息框上單擊確定後纔會消失。我試圖等待在窗體的VisibleChanged事件的事件處理程序中顯示消息框,甚至在窗體和主窗體上都調用Refresh()。在顯示消息框之前,有什麼方法可以確定第一個窗體何時完全消失?如何確保Windows窗體「完全」關閉?

編輯:

下面是一些演示如何顯示窗體的代碼。

static class Program 
{ 
    // The main form is shown like this: 
    static void Main() 
    { 
     Application.Run(new MainForm()); 
    } 
} 

public class Class1 
{ 
    // _modalForm is the first form that is displayed that won't fully go away 
    // when it is closed. 
    ModalForm _modalForm; 
    BackgroundWorker _worker; 

    public Class1() 
    { 
     _modalForm = new ModalForm(); 
     _worker = new BackGroundWorker(); 
     _worker.RunWorkerCompleted += backgroundWorker_RunWorkerCompleted 
    } 

    public void Method1() 
    { 
     _worker.RunWorkerAsync(); 

     // The first form is shown. 
     _modalForm.ShowDialog(); 
    } 


    // This code runs in the UI thread.   
    void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
    { 
     _modalForm.VisibleChanged += new EventHandler(_modalForm_visibleChanged); 
     _modalForm.Close(); 
    } 

    void _modalForm_visibleChanged(object sender, EventArgs e) 
    { 
     // When the message box is shown, the other form is still visible 
     // and remains so until I click OK. 
     MessageBox.Show("The other form was just closed."); 

     // Note: I originally tried to use the FormClosed event instead of 
     // VisibleChanged. Then I tried Deactivate, in attempt to use an event 
     // that occurred later thinking that might do the trick. VisibleChanged 
     // is the latest event that I found. 
     // 
    } 
+1

我認爲答案取決於你如何顯示主窗體。你能發表一些簡單的代碼來證明你不喜歡的行爲嗎? – Karmastan 2010-07-06 17:15:29

回答

5

我猜你是在Windows XP或Vista/Win7上關閉Aero的情況下運行你的代碼。關閉表格而不是使屏幕上的像素立即消失。 Windows窗口管理器發現表單的窗口被破壞,並顯示其下的其他窗口部分。它將傳遞WM_PAINT消息,讓他們知道他們需要重新繪製已顯示的窗口部分。

如果其中一個或多個窗口沒有主動抽取消息循環,這將無法正常工作。他們看不到WM_PAINT消息。他們不會重新繪製自己,封閉表單的像素將保留在屏幕上。

找出爲什麼這些窗口沒有響應。希望它是你的窗口,調試器可以告訴你UI線程正在做什麼。確保它沒有阻塞某物或卡在循環中。


看到編輯後:確實阻塞了,是另一種類型。 MessageBox.Show()調用是模態的,它阻止了VisibleChanged事件的完成。這延遲了表格的關閉。

使用System.Diagnostics.Debug.WriteLine()或Console.WriteLine()在Window Forms應用程序中獲取診斷信息。您會在「輸出」窗口中看到它。或者簡單地使用調試器斷點。

+0

我的確在使用Windows XP。我編輯了我的問題以包含一些代碼。我不相信UI線程被阻塞,我不確定我完全理解線程被「卡在循環中」的意義,但是表單將以模態方式顯示的事實與任何事情有關它? – YWE 2010-07-06 19:12:35

+2

@YWE:MessageBox.Show()調用只是阻止VisibleChanged事件,阻止正常窗體關閉完成。切勿在WF應用程序中使用MessageBox進行調試,請使用Debug.WriteLine()。 – 2010-07-06 19:28:31

+0

@ Hans Passant:啊,所以VisibleChanged事件必須在表單完全消失之前完全結束。消息框實際上是程序的一部分,而不是調試幫助。我嘗試使用Dispose事件的相同程序,而且它的工作方式與我想要的類似。謝謝。 – YWE 2010-07-06 19:49:02

2

形式完成關閉時Form.FormClosed事件引發。此時,所有Form.FormClosing事件處理程序都已運行,並且它們都沒有取消關閉。

Form.FormClosed替換爲Form.Closed(已棄用)在.NET 2.0框架中。