简体   繁体   中英

Prevent form from receiving mouse clicks

I am trying to block the user from clicking a button multiple times while data is being processed after it was started by the initial click.

Simply disabling the button ( buttonBackupNow.Enabled = false; ) doesn't help because if the user clicks the button multiple times even when the button is disabled, the form registers the clicks and restarts data processing as soon as the previous data processing routine.

I tried making the button invisible, still the same result. Tried disabling the form, again, the same result. So I think that the only solution is to completely ignore the clicks while data is being processed.

So, how can I stop a form from receiving user mouse clicks?

EDIT: This issue is related to the fact that I am trying to re-enable the button after data processing is finished.

Simply disabling the button (buttonBackupNow.Enabled = false;) doesn't help because if the user click the button multiple times even when the button is disabled, the form registers the clicks and restarts data processing as soon as the previous data processing routine finished.

Really? How have you accomplished that? I wasn't able to reproduce it at all. Disabling the button stopped the Click event from being triggered.

This by itself should be enough. You shouldn't have to disattach the event (as well as using other tricks). If you need resorting to that, something could be not right somewhere else (perhaps some code is re-enabling the button?).

The fact that even removing the handler doesn't do the trick for you - as you yourself stated in response to Justin Harvey 's answer - reassures me that the problem lies somewhere else.


PS. From UX perspective, disabling the button is much better than just ignoring clicks, because it gives your user some visual feedback: the command is not available now. Displaying a message: "not now, I'm doing this stuff already" might be even better perhaps. But leaving a button clickable while not reacting to clicks is bad.


Update: after OP's clarified the issue (in a comment)

Well, when the button is pressed, I immediately disable it, then the data processing sequence follows and when it finishes I re-enable the button. But I think that the issue has something to do with the fact that data processing it making the application unresponsive, yet the form still registers the clicks and the button gets pressed again after being re-enabled.

You should run this operation asynchronously (on a background thread). Use a BackgroundWorker object and reenable the button in its RunWorkerCompleted event.

It solved the problem.

You could remove the handler:

this.button.Click -= button_Click;

Then re-instate after processing.

I don't know C# but I think you can (create and) check if a variable alreadyClicked is true when you handle the event, if not, you set it to true and than handle the event normally.
In this way when the user click the second times the button, alreadyClicked is true and the code isn't executed

我可以想一下如果有很多方法可以防止这种情况,但只是一个非常快的方法是在表单上有一个布尔变量来检查用户是否已经点击了按钮,并且只在第一次执行on_click事件时执行代码他点击了按钮。

Instead of trigger whatever you are processing with the click event of the button trigger it with the submit of the form. So once the user first submit the form you just do prevent default to the form until your decide to.

None of the above answers are correct.

The true reason is: it is the main thread that executes the button clicked event handler method, and it is also the main thread that detects that there is a mouse click and decides what to do with it.

In your button click event handler you first disable the button, then do the time-consuming job, then enable the button at the end, hoping that while you are doing the time-consuming job, the following mouse clicks would have been processed and ignored. But this is not the case. The main thread only gets to look at the following mouse clicks after it finishes your event handler, and by that time the button has been re-enabled!

So what you need to do, is to disable the button in the event handler, then, at the end of that event handler, start a 100-ms timer, then let the timer re-enable the button. This way, when the main thread exits your event handler, the button remains disabled, the main thread goes and consumes the following mouse clicks and waste them, then, the timer kicks in and re-enable the button, so that you can click it again.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM