Jeff
Jeff

Reputation: 8148

Disable All Events on a Windows Form

Is there any way to temporarily disable ALL events on an windows form?

I have situation where processing on a secondary thread is being corrupted by events on the main thread. (The main thread events are modifying the contents of controls that are data-bound to variables used by the secondary thread.) Looking for a way to "lock" the form until the processing on the secondary thread finishes. (Obviously, moving processing to the main thread would do this--but it would also "freeze" the UI, which isn't what I want either.)

Upvotes: 4

Views: 5067

Answers (5)

Jeff
Jeff

Reputation: 8148

Thanks all for your excellent assistance. Really helped the decision making process. Upvotes to everyone. Ended up using a lock. (I.e. an if statement at the start of each event handler checks the lock status before continuing.) Tedious and not all that "cool" technically, but simple and it worked.

Upvotes: 1

HTTP 410
HTTP 410

Reputation: 17608

If you want to suppress all events resulting from a PostMessage, then you can implement the IMessageFilter interface and use AddMessageFilter.

This will probably trap all of the events in which you're interested. It won't trap everything, for example an event resulting from a SendMessage. To trap absolutely everything, you will need a thread-specific application hook.

Note that this will cause the UI to freeze completely, which may not be what you want. A better apporach might be to intercept the appropriate events and suppress unwanted behaviour while your background work is in progress.

Upvotes: 1

Hans Passant
Hans Passant

Reputation: 941705

This is a standard threading problem. Even if you could block the events, very hard to do, it still won't solve the problem. Because the event handler might already have started, but not yet finished, by the time you want to start blocking.

And it has a standard solution, use the lock keyword.

If that is not practical because the user needs to change several controls before you can run a query again then you need to terminate the running thread first. BackgroundWorker.CancelAsync for example. If that's not practical because it takes too long to cancel the query then you need to set the controls Enabled property to false while the query is running.

Upvotes: 2

KeithS
KeithS

Reputation: 71573

A few different options should allow you to solve this:

  • Disable any controls that would fire events that are not thread-safe,
  • Lock all code that modifies the variables, or all event-raisers, using a Monitor on the same Object, or
  • Detach and reattach all handlers.

I would go with the first option, possibly coupled with setting the cursor to an hourglass and/or setting a message in the status bar. It's simple, it works, and it doesn't cause the actual UI to freeze. I would avoid the third option as it will "break" the behavior of your form while it's working. The second option's efficacy is dependent on how you implement it; it could very easily freeze the UI which is something you don't want to do..

Upvotes: 2

Reed Copsey
Reed Copsey

Reputation: 564451

Blocking events on a form is effectively freezing the UI. Events occur as part of standard message handling in the message pump - stopping events would freeze the UI.

It would be better to disable UI features while your work is processing (such as disabling the individual buttons, etc), then re-enable them when it completes. This will allow normal events to occur, but prevent the user from triggering a button click, etc.

Upvotes: 1

Related Questions