代码之家  ›  专栏  ›  技术社区  ›  matt

如何在不阻塞的情况下显示模式对话框?

  •  0
  • matt  · 技术社区  · 5 年前

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

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

    这并不奇怪,有时会导致一些问题,但如果我们可以很容易地禁用除进度条之外的所有ui,这可能会有所帮助。

    我是从这里读到这个答案的: https://stackoverflow.com/a/5183623/259846

    编辑: 模态对话框只是一个禁用所有其他用户界面的对话框-只有模态对话框可以与之交互。这与显示此对话框的操作是否被阻止是分开的。我看不出为什么理论上不能有一个函数,在关闭之前不阻塞地显示一个模式对话框。

    我想显示一个进度条,我想让这个进度条随着进程的进展而更新,不管我怎么做,事实是,如果你想更新一个对话框,你必须更新整个UI。因此,我希望禁用除进度窗口之外的其他UI,以便在我的进程正在进行时无法与之交互。

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

    0 回复  |  直到 5 年前
        1
  •  1
  •   Bjorn    5 年前

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

    例如: Button.Enabled = false;

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

    你也可以在你不能点击的东西前面放一个透明的矩形。然后在对话框关闭时将其隐藏。

        2
  •  0
  •   matt    5 年前

    我想了一个办法。 我的问题可能没有清楚地指出我的用例,这个解决方案仍然使用阻塞调用来创建模式对话框,但是仍然允许我在对话框打开时执行“做工作,更新进度”循环。

    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();