如何等到对话框真正关闭

Posted

技术标签:

【中文标题】如何等到对话框真正关闭【英文标题】:How to wait until the dialog is really closed 【发布时间】:2019-09-22 00:39:35 【问题描述】:

软件通过一些计算启动线程,然后将另一个Form 显示为与ShowDialog 的等待对话框。当BackgroundWorker 线程完成其工作时,FormRunWorkerCompleted 事件中关闭,另一个计算以另一个Form 作为等待对话框开始(再次使用ShowDialog)。

问题是第一个等待对话框仍然可见,直到第二个等待对话框关闭。第一个对话框真正关闭后如何等待显示第二个对话框?

重现的简单代码:

private BackgroundWorker _bgw = new BackgroundWorker();
private Form2 _msg = new Form2();
private Form3 _msg2 = new Form3();

public Form1()

    _bgw.DoWork += BgwDoWork;
    _bgw.RunWorkerCompleted += BgwRunWorkerCompleted;
    _bgw.RunWorkerAsync();
    _msg.ShowDialog();


private void BgwDoWork(object sender, DoWorkEventArgs e)

    System.Threading.Thread.Sleep(5000);


private void BgwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

    _msg.Close();
    _msg2.ShowDialog();

【问题讨论】:

也许我没有正确理解你,但在你的代码中 _msg.Close() 在 _msg2.ShowDialog() 之前,你的问题是,虽然你的代码写得很好,但它没有按预期工作?如果这是您的问题,只需在这两件事之间添加以下行 Application.DoEvents();这个节目可以解决问题 这不是真的。 Application.DoEvents() 没有帮助。 【参考方案1】:

注意 ShowDialog() 是一个阻塞调用。当你显示 _msg2 时,你还没有从构造函数返回。

这是一个快速修复:

public Form1()

    _bgw.DoWork += BgwDoWork;
    _bgw.RunWorkerCompleted += BgwRunWorkerCompleted;
    _bgw.RunWorkerAsync();
    _msg.ShowDialog();
    _msg2.ShowDialog();   // here


private void BgwRunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)

    _msg.Close();
    //_msg2.ShowDialog();  // not here

【讨论】:

您的解决方案有效,但如果我仅在计算后才知道是否需要第二个对话框,该怎么做?有没有办法或者我必须将结果保存到某个私有财产,然后在我调用ShowDialog的方法中对其进行评估? 当然,您可以使用 DialogRsult (而不是 _msg.Close() )或将属性添加到 Form2 或 ... 但是您可以通过将 Bgw 替换为 Task 并使用 async & await 来获得更好、更自然的流程。 谢谢。我只想对用.NET framework 4 编写的旧项目进行一些 更改,所以asyncawait 是我必须忘记 一段时间的事情:- )

以上是关于如何等到对话框真正关闭的主要内容,如果未能解决你的问题,请参考以下文章

Swing 对话框如何工作?

Selenium - 如何等到页面完全加载[重复]

如何等到当前位置对话框回答运行方法?

如何等到模态对话框在ios中返回结果

Angular 6 Material - 等待 Mat 对话框关闭

Tkinter:等待用户点击