Button disable and enable

前端 未结 6 2287
北海茫月
北海茫月 2021-02-20 16:35

I have a vb.net based windows application, where when \"GO\" button is clicked a bunch of data is loaded into DB. So in my application as soon as \"GO\" button is clicked I want

相关标签:
6条回答
  • 2021-02-20 17:10

    I just tried disabling a button, Updateing the form, Sleeping, and enabling it again. It still performed the click (A click that was done while it "slept" with the button disabled) after it was enabled.

    I guess forms "remember" clicks.

    (EDIT: I did this in C#.)

    0 讨论(0)
  • 2021-02-20 17:11

    If your btnGo_Click() is ran inside main thread, UI could not be updated correctly inside a time-consuming task.
    The best way you can do what you need is running your method in a BackgroundWorker.

    0 讨论(0)
  • 2021-02-20 17:12

    The button click event is handled as soon as the UI thread has idle time. After you disable your button, the UI thread is keept busy by your code. At the end of your method, you re-enable the button, and after that you exit the method and allow for idle time. As a consequence, the button will already be enabled at the point in time where the click event is handled, so your click is "recognized".

    The solution is, as others already suggested, to use a Backgroundworker.

    Dont try to use doEvents() as a solution (never do), since this would be prone to introduce other subtle problems. That said, you can prove the above explanation with some experimental doEvents in your code. You will see that the click is discarded if a doEvents is performed before the button gets re-enabled. On the other hand, performing a doEvents directly after the button.disable (to "update the GUI") will not help if it is executed before the click.

    0 讨论(0)
  • 2021-02-20 17:19

    Since you're trying to execute a function that can take some time, I'd advise you to make use of threading. In .NET there's a BackgroundWorker component which is excellent for performing tasks asynchronous.

    On button click, invoke the BackgroundWorker like this:

    if not bgwWorker.IsBusy then
       btnGo.enabled = false
       bgwWorker.RunWorkerAsync()
    end if 
    

    And use the completed event to enable the button again:

    Private Sub bgwWorker_DoWork(ByVal sender As System.Object, _
                     ByVal e As System.ComponentModel.DoWorkEventArgs) _
                     Handles bgwWorker.DoWork
    ' Do your things    
    End Sub
    
    Private Sub bgwWorker_RunWorkerCompleted(ByVal sender As System.Object, _
                             ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) _
                             Handles bgwWorker.RunWorkerCompleted
    ' Called when the BackgroundWorker is completed.
    btnGo.enabled = true
    End Sub
    

    In the example above, I've used bgwWorker as the instance of a BackgroundWorker.

    0 讨论(0)
  • 2021-02-20 17:23

    It's usually not a good idea to manage the state of a submit button. Instead, perform validation on submit.

    0 讨论(0)
  • 2021-02-20 17:35

    You're not doing anything wrong. The problem is that the UI doesn't get updated until the code inside of your event handler method finishes executing. Then, the button is disabled and immediately enabled in rapid sequence.

    That explains why if you forget to reenable the button control at the end of the event handler method, it is still disabled—because you told it to disable the button in the first line of the method.

    This is a classic case of why you should never perform long-running computational tasks inside of an event handler method, because it blocks the UI from being updated. The computation actually needs to happen on a separate thread. But don't try to create the thread manually, and definitely don't try to update your UI from a separate thread. Instead, use the BackgroundWorker component to handle all of this for you automatically. The linked MSDN documentation has a great sample on how to use it.

    Disable the button before starting the BackgroundWorker, and then re-enable it in its Completed event, signaling the completion of your database load.

    0 讨论(0)
提交回复
热议问题