简体   繁体   English

防止表单接收鼠标点击

[英]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. 简单地禁用按钮( buttonBackupNow.Enabled = false; )也无济于事,因为即使按钮​​被禁用,如果用户多次单击该按钮,表单会在上一次数据处理例程后立即注册点击并重新启动数据处理。

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. 简单地禁用按钮(buttonBackupNow.Enabled = false;)也无济于事,因为即使按钮​​被禁用,如果用户多次单击按钮,表单会在上一次数据处理程序完成后立即注册点击并重新启动数据处理。

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. 禁用该按钮会停止触发Click事件。

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. 事实上即使删除处理程序也不能解决问题 - 正如你自己在回答Justin Harvey的回答时所说的那样 - 让我放心,问题出在其他地方。


PS. 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) 更新:在OP澄清问题后(在评论中)

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. 使用BackgroundWorker对象并在其RunWorkerCompleted事件中重新启用该按钮。

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. 我不知道C#但是我认为你可以(创建并)检查一个变量yetClicked在你处理事件时是否为真,如果没有,你将它设置为true并且正常处理事件。
In this way when the user click the second times the button, alreadyClicked is true and the code isn't executed 这样,当用户单击第二次按钮时, yetClicked为true且代码未执行

我可以想一下如果有很多方法可以防止这种情况,但只是一个非常快的方法是在表单上有一个布尔变量来检查用户是否已经点击了按钮,并且只在第一次执行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. 所以你需要做的是,在事件处理程序中禁用按钮,然后,在该事件处理程序的末尾,启动一个100毫秒的计时器,然后让计时器重新启用该按钮。 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. 这样,当主线程退出事件处理程序时,按钮保持禁用状态,主线程继续消耗以下鼠标并浪费它们,然后,计时器启动并重新启用按钮,以便您可以单击它再次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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