Chris
Chris

Reputation: 1731

Disable form while BackgroundWorker is busy?

I don't want the user to interact with my application while a certain backgroundworker is busy (working). I created this bgw so that the application doesn't look frozen when it's working. But now users can move around in the app. How do I disable my form/application?

Thanks!

Upvotes: 7

Views: 12093

Answers (5)

Marcus Adams
Marcus Adams

Reputation: 53850

It is easier to manage disabling certain controls by placing them inside a panel and disabling that panel rather than disabling individual controls:

controlPanel.Enabled = false;

A common way to block other tasks, that may meet your needs, is by showing a top most form with a progress bar. I've implemented this in the past with success. Other programs do the same thing. For example, in WinRAR, when the applciation is busy extracting or compressing files, the application shows a top most form. It looks like a "modal" form, but in fact, you can still click on the other functions, to which WinRAR asks, "Do you wish to abort the current operation?"

Disabling the entire application is often not necessary and may not be intuitive. So, ask yourself if you really need to block interaction with the form. For example, I have an application that takes some time to complete certain tasks. I provide a progress bar indicator for that particular piece of work, but you can still interact with the application to start additional tasks that run simultaneously. Even if I only allowed you to perform a single task at a time, you still may want to view the help file or set application preferences while the task was running. In addition, I give the user a button that allows them to stop the task. Disabling the form would prevent this type of interaction.

Upvotes: 1

Garo Yeriazarian
Garo Yeriazarian

Reputation: 2533

You could also create a modal "busy splash" dialog that is shown when the background task starts and removed programmatically when the task ends. You could put a little animation in that box too to let the users know that something is going on. You would also need to make sure they don't close the dialog manually (only allow it to be closed programmatically).

Upvotes: 4

Guy Starbuck
Guy Starbuck

Reputation: 21873

I agree with @michael-todd in his comment above, disabling individual controls/navigation buttons/etc. while the background worker is working seems like a fairly good solution. This would give you fine-grained control over what the user can do during the specific background operation.

You could:

  1. Create methods to enable or disable all appropriate navigation/interaction controls (by setting their Enabled property to true/false, etc. as appropriate for each control)
  2. Call the "Disable" method from your code right before you call StartWorkerAsync() on your background worker
  3. In the event handler for RunWorkerCompleted, call the "Enable" method to re-enable the view for user input

Upvotes: 1

Codex
Codex

Reputation: 1022

Another possible way could be that you "filter out" all the input to the application. This could be done by listening to the "KeyDown" and "MouseButtonDown". Once the background job is triggered you could set the FILTER_INPUT flag to true and reset it once done. If the FILTER_INPUT flag is set then could cancel all the Key and Mouse events.

This may not be the most efficient since all KeyPress and Clicks are going to go thro the Filter check.

Upvotes: 0

Fredrik Mörk
Fredrik Mörk

Reputation: 158319

Perhaps set Enabled to false?

this.Enabled = false;

That is a bit drastic though, since it also prevents the form from being moved, resized or event closed. A better approach would be to put a Panel control in your form, that has Dock = Fill, and put our other controls into that Panel. Then you can instead use the Enabled property of the Panel to prevent further user input.

Note thought that the user will be able to close the form, so that should be handled gracefully in some way.

Upvotes: 15

Related Questions