如何确保Windows窗体“完全”关闭?

时间:2010-07-06 17:12:46

标签: c# vb.net winforms

我在Windows窗体应用程序中有一个表单,我想在主窗体上显示,关闭它,然后立即使用MessageBox.Show()显示一个对话框。但是当显示消息框时,第一个表单仍然显示,并且在我单击消息框上的“确定”之前它不会消失。我试图在表单的VisibleChanged事件的事件处理程序中显示消息框,甚至在表单和主表单上调用Refresh()。有没有办法在显示消息框之前确定第一个表单何时完全消失?

编辑:

以下是一些代码,演示了如何显示表单。

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.
        // 
    }

3 个答案:

答案 0 :(得分:5)

我猜你在Windows XP或Vista / Win7上运行你的代码并关闭了Aero。关闭表单使屏幕上的像素立即消失。 Windows窗口管理器看到窗体的窗口被破坏,这显示了其下面的其他窗口的部分。它将传递一条WM_PAINT消息,让他们知道他们需要重新绘制已经显示的窗口部分。

如果其中一个或多个窗口没有主动泵送消息循环,则无法正常工作。他们看不到WM_PAINT消息。他们不会重新绘制自己,封闭形式的像素将保留在屏幕上。

找出这些窗口没有响应的原因。希望它是您的窗口,调试器可以显示UI线程正在做什么。确保它没有阻塞某些东西或卡在一个循环中。


在看到编辑之后:确实存在阻塞,不同类型。 MessageBox.Show()调用是模态的,它可以防止VisibleChanged事件完成。这延迟了表格的结束。

使用System.Diagnostics.Debug.WriteLine()或Console.WriteLine()在Window Forms应用程序中获取诊断信息。您将在“输出”窗口中看到它。或者只是使用调试器断点。

答案 1 :(得分:2)

表单完成关闭时会引发Form.FormClosed事件。此时,所有Form.FormClosing事件处理程序都已运行,并且没有一个取消关闭。

Form.FormClosed替换了.NET 2.0框架中的Form.Closed(已弃用)。

答案 2 :(得分:1)