如何显示不阻塞的模式对话框?

时间:2019-10-21 06:29:10

标签: c# winforms user-interface

我想将对话框显示为模态(即,阻止与应用程序中所有其他ui的所有交互),但我不希望该调用阻止执行,我该怎么做?

这并不漂亮,但是由于我无法控制的原因,我们只有一个线程,无法创建更多线程。 当前,当我们进行耗时的进度时,我们希望显示一个进度条,但是为了在流程进行时对其进行更新,我们必须调用DoEvents()(eek)。

这有时会引起一些问题,这并不奇怪,但是如果我们可以轻松禁用除进度条以外的所有ui,那可能会有所帮助。

我在这里阅读以下答案得到了这个主意: https://stackoverflow.com/a/5183623/259846

编辑: 模态对话框只是禁用所有其他UI的对话框-只能与模态对话框进行交互。这与显示此对话框的操作是否被阻塞是分开的。从理论上讲,我看不出您为什么不能拥有一个显示模式对话框而不会阻塞的功能,直到关闭该对话框。

我想显示一个进度条,并且我希望该进度条随着流程的进展而更新,我不管这样做如何,事实是,如果您想更新一个对话框,您可以必须更新整个用户界面。因此,我希望禁用UI的其余部分(进度窗口除外),以便在过程进行期间无法与之交互。

是的,我只能有一个线程,没有并行性。

2 个答案:

答案 0 :(得分:1)

在打开对话框时,请手动禁用所有其他元素。然后在关闭包装盒时启用它们。

例如:  Button.Enabled = false;

检查此内容以禁用所有控件 How to disable all controls on the form except for a button?

您也可以在所有无法单击的内容前面放置一个透明矩形。然后在对话框关闭时将其隐藏。

答案 1 :(得分:0)

我想到了一种方法。 我的问题可能无法清楚地表明我的用例,该解决方案仍然使用阻塞调用来创建模态对话框,但仍允许我在打开对话框的情况下执行“完成工作,更新进度”循环。

var progress = new Form();
this.BeginInvoke(new Action(() =>
{
    for (int i = 0; i < 100; i++)
    {
        System.Threading.Thread.Sleep(16); // do a bit of my process
        // Update progress dialog
        Application.DoEvents();
    }
    progress.Close();
}));
progress.ShowDialog();