How to Use Showdialog Without Blocking All Forms

Is it possible to use ShowDialog without blocking all forms?

If you run Form B on a separate thread from A and C, the ShowDialog call will only block that thread. Clearly, that's not a trivial investment of work of course.

You can have the dialog not block any threads at all by simply running Form D's ShowDialog call on a separate thread. This requires the same kind of work, but much less of it, as you'll only have one form running off of your app's main thread.

ShowDialog without Blocking Execution Code but Block UI

If you don't want to block the code, then you want to call .Show

In other words, you want:

can3.Show(this);
this.Enabled = false; //disable the form so the UI is blocked

//...do our stuff now that code is not blocked while the UI is blocked

//All done processing; unblock the UI:
this.Enabled = true;

In fact, that is all that ShowDialog does: disable the form, and later re-enable it. In psuedo-code:

void ShowDialog(IWindowHandle Owner)
{
this.Show(Owner);

try
{
//Disable the owner form
EnableWindow(Owner, false);

repeat
{
Application.DoEvents();
}
until (this.DialogResult != DialogResult.None);
}
finally
{
//Re-enable the UI!
EnableWindow(owner, true);
}
}

You can steal all those concepts, and replace guts with whatever you want:

void DoStuffWithTheThing()
{
can3.Show();

try
{
//Disable the owner form
this.Enabled = false;

//todo: Solve the P=NP conjecture
}
finally
{
//Re-enable the UI!
this.Enabled = true;
}
}

ShowDialog without Blocking Caller

I ended up BeginInvoke'ing a ShowDialog:

myForm.BeginInvoke(new Action(() => new LoadingForm().ShowDialog()));

that has the desired effect of letting code after that line continue to run and still blocking all interaction with myForm.

show a form(dialog) without blocking the current thread (progressbar example)

There is two different call that exist in a form:

myForm.ShowDialog();

Is the modal version that block the thread calling it. It is used for popup that must prevent other action from taking place (like save dialog).

myForm.Show(IWin32Window owner);

Is the non-modal version. It doesn't block the current thread, but doesn't return any result. However, you must pass it the owner, often like this:

myForm.Show(this);

Winform - Continue from a ShowDialog without hiding the window

You can't do that. At least there is not an easy way that I am aware of. One way to tackle that is to change your code as follows:

//C#-ish pseudocode based on OPs example; doesn't compile
class frmProgress : Form
{
// Standard stuff

public void DoSomeWorks()
{
async Task.Run(() => RunWork1());
ShowDialog();
}

void RunWork1()
{
// Do a lot of things including update UI

if (_iLikeTheResultOfWork1)
{
async Task.Run(() => RunWork2());
}
else
{
Hide();
}
}

void RunWork2()
{
// Do a lot of things including update UI

Hide();
}
}

EDIT For those complaining the code doesn't compile, they are right. But this is the best the OP will get with that code sample and that's the reason I guess he is mercilessly downvoted.

But to make the answer more relevant to others, my suggestion is don't hide the progress form between the the 2 tasks, hide it when you are sure that the tasks have ended. All these by respecting the threading model of the context you are working on, something the OP's code doesn't do. Manipulating the UI in Winforms from methods that will eventually run in other threads won't work.



Related Topics



Leave a reply



Submit