0

I want to show a dialog as modal( i.e. blocks all interaction with all the other ui in my application) But I don't want that call to block execution, how do I do that?

This isn't pretty, but for reasons out of my control, we just have one thread, and can't create more. currently when we do a time consuming progress, we want to show a progress bar, but in order for it to update while the process is progressing, we have to call DoEvents() (eek).

This unsurprisingly causes a few issues sometimes, but if we could easily disable all ui except the progress bar, that might help.

I got this idea from reading this answer here: https://stackoverflow.com/a/5183623/259846

Edit: A modal dialog is simply one that disables all other UI - only the modal dialog can be interacted with. This is separate from whether or not the operation to show this dialog is blocking or not. I don't see any reason why you couldn't in theory have a function that shows a modal dialog box without blocking until the box is closed.

I want to show a progress bar, and I want this progress bar to update as a process progresses, I doesn't matter how I go about doing this, the fact is, that if you want to update one dialog, you have to update the whole UI. As such I want the rest of the UI except for the progress window to be disabled so it can't be interacted with while my process is in progress.

And yes, I can only have one thread, no parallelism.

matt
  • 4,042
  • 5
  • 32
  • 50
  • Run execution on other thread. – Michał Turczyn Oct 21 '19 at 06:30
  • Its unclear what you are asking. if you don't want to block, use `ShowDialog`, if you don't want to use `DoEvents`, use the *async and await pattern* – TheGeneral Oct 21 '19 at 06:33
  • No blocking modal dialog on a single thread? Either your dialog is modal, or it´s non-blocking. Both isn´t possible. – MakePeaceGreatAgain Oct 21 '19 at 06:36
  • Is single thread a hard constraint? I mean, even BackgroundWorker is not an option, right? – Stas Ivanov Oct 21 '19 at 06:40
  • @HimBromBeere, ShowDialog is the way to show a modal dialog, and blocks... How would I use async and await to show a modal dialog? – matt Oct 21 '19 at 07:02
  • It doesn't matter with or without dialog, but you have to run long running code in parallel. It should be possible to invoke UI update for background window or dialog (not sure where your progress bar is). – Sinatr Oct 21 '19 at 07:15
  • *"I can only have one thread, no parallelism"* - why is that? – Sinatr Oct 21 '19 at 07:16
  • Because I'm working on a 3 million line code base that has not been designed for parallelism at all. – matt Oct 21 '19 at 07:23
  • Yeah showdialog is modal, how ever show() is not, I made a mistake in my previous comment – TheGeneral Oct 21 '19 at 07:26

2 Answers2

1

Disable all other elements manually when opening the DialogBox. Then enable them when closing the box.

for example: Button.Enabled = false;

Check this out for disabling all controls How to disable all controls on the form except for a button?

You can also put up a transparent rectangle in front of everything that you can't click through. Then hide it when dialogbox closes.

Bjorn
  • 181
  • 2
  • 11
  • 1
    I sure hope this isn't the best answer, but it is correct. – matt Oct 21 '19 at 07:01
  • You can do recursive blocking on all elements in WinForms. Check this out: https://stackoverflow.com/questions/13446129/how-to-disable-all-controls-on-the-form-except-for-a-button – Bjorn Oct 21 '19 at 07:44
0

I've thought of one way of doing it. My question probably doesn't clearly indicate my use case, this solution still uses the blocking call to create the modal dialog, but still allows me to execute my 'do work, update progress' loop with the dialog open.

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();
matt
  • 4,042
  • 5
  • 32
  • 50