views:

1493

answers:

5

My mdi VB.Net application performs a long operation on some data. Ideally I should use a separate thread to prevent the dreaded “Not Responding” message.

My problem is if I use a separate thread users then have the ability to click on other controls in the application which can directly affect the operation my background thread is working on, creating an error.

Is there any way to prevent all the mdi windows, toolbars and other controls from receiving mouse clicks and keyboard input during my background thread’s operation?

Or is there a way to clear the message que before performing a Application.DoEvents?

Thanks

+4  A: 

I would say that the best choice when you don't want a user to click on a control is to set Enabled to False for that control.

CLARIFICATION: Setting Enabled to False for a parent control will also disable any children. So, setting Enabled to False on the main window and and MDI windows, will do the trick.

Dustin Campbell
Yes the problem with several mdi windows open there can be many many controls, toolbars, ect. to turn off. It can be done but I was hoping for a broader solution.
Setting Enabled to False on a parent control will also disable the children. So, setting Enabled to false for the main window and each MDI window, would do the trick.
Dustin Campbell
I forgot about that. That would help. Thanks
+2  A: 

There are a couple of ways of disabling the controls but I'm not sure it's what you want.

If you have a main window which is completely disabled while a background thread is processing then why go through the overhead of processing on the background? The advantage of processing on the background is to allow the user to still work with the application while you process data.

I think a better approach would be to take Dustin's route and selectively disable certain controls that can affect the background operation. Or make your background operation independent of the UI while it's processing.

If you tell us a little bit more about how your Main Window and Background thread interact we may be able to give you a better solution.

JaredPar
A: 

Hide all forms and only show the one main form. Then disable the Toolbar/Menu if you have either. Then have a status bar with a progress bar and when it gets done, unhide the form the user was working on.

Lucas McCoy
A: 

When you are using a statusbar or a progress bar while your background thread is processing some longduring task, disabling your form will also disable your progress/status bar from updating. So what you should do in this case is disable every other control exept from the one that needs te be kept active (e.g. like a progressbar).

List<Control> lstControls = GetAllControls(this.Controls);

                foreach (Control ctrl in lstControls)
                {
                if (ctrl.GetType().Name.ToLower().Contains("progressbar")                     {
                        ctrl.Enabled = true;
                    }
                    else
                    {
                        ctrl.Enabled = false;
                    }
                }
Mez
A: 

Use a thread and display a modal dialog that shows the user the progress of your task and gives the user the option to cancel it.

The modal dialog will automatically prevent input (the parent may have to be the mdi window itself.)

(Please do not use hacks like hiding or disabling controls or windows. And please, please, please! do not use DoEvents.)