Results 1 to 22 of 22

Thread: Disable input during processing.

  1. #1

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2001
    Posts
    485

    Disable input during processing.

    Hi all,

    I have a form with several buttons on it. When a button is pressed, it will execute some remoting proxy method on the server. There is some delay in the process before there is a result returned from server.

    Currently, I tried to disable the button in the _Click event, hoping that a 2nd, 3rd and the following clicks would not be registered. Unfortunately, those input from the mouse clicks were queued by Windows.

    So once the _Click event has finished running, it will immediately get executed again due to the earlier clicking.

    I tried to create a form (Notice) to display some status message, hoping that clicks won't be registered on the button. Despite setting the form to maximize and on top of the caller form, the clicks still get registered.

    Then I thought of using .ShowDialog(). Unfortunately, it halts the processing until I close the form. So I did something more complicated by passing in the method into Notice form, so that it would execute the _Click method via an address pointer.

    Unfortunately, after all these coding. The buttons still get registered with the mouse clicks.

    So now, is there any way to overcome this clicking queue that Windows registered?

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Disable input during processing.

    Just disable the Button, then enable it again when you're done.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,423

    Re: Disable input during processing.

    vb Code:
    1. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    2.     Button1.Enabled = False
    3.     'run your code
    4.     Button1.Enabled = True
    5. End Sub

  4. #4

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2001
    Posts
    485

    Re: Disable input during processing.

    Did the disable enable thing. Doesn't seem to work.

    I'll post sample code later.

    Thanks peeps.

  5. #5

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2001
    Posts
    485

    Re: Disable input during processing.

    Hi all, as promised, the sample code:

    Just a form, with 4 buttons.

    When you run it, click on Button1 for 3 times, then Button2 for 1 time.

    Wait for it to run. You can move your mouse away or whatnot. You'll notice that the Button1 will be executed 3 times by looking at the counter on Button3.Text.

    Thank you.

    vb Code:
    1. Public Class Form1
    2.  
    3.     Dim intCount As Integer = 1
    4.  
    5.     Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    6.         Button3.Text = intCount.ToString()
    7.     End Sub
    8.  
    9.     Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    10.         Dim btnTmp As Button = CType(sender, Button)
    11.  
    12.         btnTmp.Enabled = False
    13.  
    14.         'sleep for 1 second
    15.         System.Threading.Thread.Sleep(1000)
    16.  
    17.         'update button 3
    18.         intCount += 1
    19.         Button3.Text = intCount.ToString
    20.  
    21.         'sleep again for 1 second
    22.         System.Threading.Thread.Sleep(1000)
    23.  
    24.         btnTmp.Enabled = True
    25.     End Sub
    26.  
    27.  
    28.     Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    29.         MessageBox.Show("No tricks here")
    30.     End Sub
    31.  
    32.     Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
    33.         MessageBox.Show("I just want to go home!")
    34.         Me.Close()
    35.     End Sub
    36.  
    37.     Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
    38.         Dim btnTmp As Button = CType(sender, Button)
    39.  
    40.         intCount += 1
    41.         btnTmp.Text = intCount.ToString
    42.     End Sub
    43. End Class
    Last edited by Harddisk; Mar 22nd, 2011 at 07:45 AM.

  6. #6

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2001
    Posts
    485

    Re: Disable input during processing.

    I am attaching the sample codes for the forms.

    Just add them into your Project/Solution to test.

    Thanks.
    Attached Files Attached Files

  7. #7

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2001
    Posts
    485

    Re: Disable input during processing.

    (bump)

    Anyone?

  8. #8

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2001
    Posts
    485

    Re: Disable input during processing.

    (1 final bump)

    No 1 got a solution or workaround for this?

  9. #9
    Junior Member
    Join Date
    Feb 2011
    Posts
    27

    Re: Disable input during processing.

    Well, if you're still looking I think you just have to reference the buttons directly in code:
    Code:
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Button1.Enabled = False
            System.Threading.Thread.Sleep(1000)
            Button1.Enabled = True
        End Sub
    I tested this and as soon as I clicked Button1 it became disabled for 1 second
    Last edited by GDeRousse; Mar 24th, 2011 at 01:29 PM.

  10. #10
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,423

    Re: Disable input during processing.

    Quote Originally Posted by GDeRousse View Post
    Well, if you're still looking I think you just have to reference the buttons directly in code:
    Code:
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Button1.Enabled = False
            System.Threading.Thread.Sleep(1000)
            Button1.Enabled = True
        End Sub
    I tested this and as soon as I clicked Button1 it became disabled for 1 second
    try harddisk's code. seems to be a vs bug

  11. #11

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2001
    Posts
    485

    Re: Disable input during processing.

    Quote Originally Posted by GDeRousse View Post
    Well, if you're still looking I think you just have to reference the buttons directly in code:
    Code:
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
            Button1.Enabled = False
            System.Threading.Thread.Sleep(1000)
            Button1.Enabled = True
        End Sub
    I tested this and as soon as I clicked Button1 it became disabled for 1 second
    If you read my earlier description, I wasn't having problem about disabling button, but rather disabling mouse click/input.

    Try to do multiple click at 1 shot, for eg, 3 - 5 times. Then move your mouse away. Even when the button was disabled, it still registers the follow clicks.

    Try it out.

  12. #12

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2001
    Posts
    485

    Re: Disable input during processing.

    Quote Originally Posted by .paul. View Post
    try harddisk's code. seems to be a vs bug
    Hi Paul,

    Does that mean, if I run it in "Release" mode, it might not occur? Though I haven't tested that (call via function pounter) using Release code, but the disable button definitely won't work the way I want.

  13. #13
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,423

    Re: Disable input during processing.

    no. unfortunately that's not what i meant.
    but i did try your code + you're right it doesn't work + none of the workarounds i tried worked either

  14. #14

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2001
    Posts
    485

    Re: Disable input during processing.

    Quote Originally Posted by .paul. View Post
    no. unfortunately that's not what i meant.
    but i did try your code + you're right it doesn't work + none of the workarounds i tried worked either
    Hi Paul,

    Thanks for taking the effort of actually trying out the code.

    I might consider trying MouseDown/MouseUp event to see if it works.

    If not, then I guess I'll go with threading, which might work, I guess.

    Will post it up here later with sample code.

  15. #15
    VB Addict Pradeep1210's Avatar
    Join Date
    Apr 2004
    Location
    Inside the CPU...
    Posts
    6,614

    Re: Disable input during processing.

    You are processing on the UI thread. Try processing on a secondary thread instead.

    vb.net Code:
    1. Dim processing As Boolean
    2. Dim counter As Integer
    3.  
    4. Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, MyButton1.Click
    5.     If Not processing Then
    6.         Dim th As New Threading.Thread(AddressOf DoProcess)
    7.         th.Start()
    8.     End If
    9. End Sub
    10.  
    11. Sub DoProcess()
    12.     processing = True
    13.     Threading.Thread.Sleep(1000)
    14.     counter += 1
    15.     SetButtonText(counter.ToString)
    16.     Threading.Thread.Sleep(1000)
    17.     processing = False
    18. End Sub
    19.  
    20. Private Delegate Sub SetButtonTextInvoker(ByVal t As String)
    21. Private Sub SetButtonText(ByVal text As String)
    22.     If Button2.InvokeRequired Then
    23.         Button2.Invoke(New SetButtonTextInvoker(AddressOf SetButtonText), text)
    24.     Else
    25.         Button2.Text = text
    26.     End If
    27. End Sub
    Pradeep, Microsoft MVP (Visual Basic)
    Please appreciate posts that have helped you by clicking icon on the left of the post.
    "A problem well stated is a problem half solved." — Charles F. Kettering

    Read articles on My Blog101 LINQ SamplesJSON ValidatorXML Schema Validator"How Do I" videos on MSDNVB.NET and C# ComparisonGood Coding PracticesVBForums Reputation SaverString EnumSuper Simple Tetris Game


    (2010-2013)
    NB: I do not answer coding questions via PM. If you want my help, then make a post and PM me it's link. If I can help, trust me I will...

  16. #16

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2001
    Posts
    485

    Re: Disable input during processing.

    Hi Pradeep,

    That was in fact what I was about to try next. Unfortunately, there were many extra coding required just for a simple task to be achieved here.

    I was still searching for a PropertyInvoker or something similar which could perform thread-safe operation on setting Property values dynamically, rather than creating extra Subs to handle the settings of property.

    Thanks again for the effort.

  17. #17

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2001
    Posts
    485

    Re: Disable input during processing.

    Holy cr*p!

    The simple example here works very well, but for my actual method to work out in order for the cross-thread to work, it's too much of a trouble.

    Try declaring "counter" as public variable under MyApplication Class. Then do the update accordingly as per DoProcess sub. Problem is, how do I cross-thread to MyApplication's thread to update the variable?

  18. #18
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Disable input during processing.

    You don't have to "cross-thread" anything to update a variable. You need to invoke a method on the UI thread to access the UI. That's all. Doing so is not difficult. You simply write your method as you normally would, then identify each section that accesses the UI and refactor that into its own method. You then use the ISynchronizeInvoke interface or the SynchronizationContext class to invoke that method on the UI thread. The main reason people have issues with this is because they don't understand WHY they're doing it. If you understand the WHY then the WHAT is completely logical.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  19. #19

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2001
    Posts
    485

    Re: Disable input during processing.

    Trying to wrap the Event with

    vb Code:
    1. If Me.InvokeRequired Then
    2.   Me.Invoke(bla bla bla)
    3. Else
    4.   '   actual code execution
    5. End If
    Somehow now my pop up form (ShowDialog() after executing the threading object) is not showing most of the time. With the ShowDialog(), I could somehow block the subsequent mouse clicks to the button, along with setting button disable.
    Last edited by Harddisk; Mar 25th, 2011 at 04:22 AM.

  20. #20
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: Disable input during processing.

    Let's say that you have a Button. In the Click event handler, you disable the Button, do some work and then re-enable the Button. Now, let's say that you click the Button and then, while the work is being done, you click it again. On the second click, because the UI thread is busy doing something else, the click doesn't get processed. Only once the work is done is the UI thread freed up to process the second click. By then, the Button has been re-enabled so the Click event does get raised.

    Now, this could be construed as a bug but it's really an example of why you aren't supposed to perform long-running tasks on the UI thread.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  21. #21

    Thread Starter
    Hyperactive Member
    Join Date
    Mar 2001
    Posts
    485

    Re: Disable input during processing.

    Quote Originally Posted by jmcilhinney View Post
    Let's say that you have a Button. In the Click event handler, you disable the Button, do some work and then re-enable the Button. Now, let's say that you click the Button and then, while the work is being done, you click it again. On the second click, because the UI thread is busy doing something else, the click doesn't get processed. Only once the work is done is the UI thread freed up to process the second click. By then, the Button has been re-enabled so the Click event does get raised.

    Now, this could be construed as a bug but it's really an example of why you aren't supposed to perform long-running tasks on the UI thread.
    I'm not sure if it's a bug or just how Windows queued the inputs from the I/O.

    As for the long running task. Well, the button click will invoke remote methods to retrieve some data, then print something via the printer. No matter how fast it goes, it still takes 500ms - 1000ms at least and sometimes takes about 2 seconds. Maybe my existing machine which run the program was a Pentium4, hence the delay. But I do want to make sure that during the delay of data retrieval and printing, any user interactions would not be registered, or they are blocked. Cause I get complains from users that, multiple printings were generated due to the delay and user clicked on it multiple times.



    EDIT: Attached the most current test button code. Both Invokes gave different behaviour. Button1 has better response and closer to what I want. Button2 is easier to code by wrapping the Invoke code in the IF's statement, but the dialog doesn't close properly.
    Attached Files Attached Files
    Last edited by Harddisk; Mar 25th, 2011 at 05:54 AM.

  22. #22
    VB Addict Pradeep1210's Avatar
    Join Date
    Apr 2004
    Location
    Inside the CPU...
    Posts
    6,614

    Re: Disable input during processing.

    Read jm's posts again.. I think he has explained it very clear and complete. I don't have anything to add to it.
    Pradeep, Microsoft MVP (Visual Basic)
    Please appreciate posts that have helped you by clicking icon on the left of the post.
    "A problem well stated is a problem half solved." — Charles F. Kettering

    Read articles on My Blog101 LINQ SamplesJSON ValidatorXML Schema Validator"How Do I" videos on MSDNVB.NET and C# ComparisonGood Coding PracticesVBForums Reputation SaverString EnumSuper Simple Tetris Game


    (2010-2013)
    NB: I do not answer coding questions via PM. If you want my help, then make a post and PM me it's link. If I can help, trust me I will...

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width