Solved

VB.NET button still works when disabled?

Posted on 2012-04-05
16
345 Views
Last Modified: 2012-06-27
I have a simple VB.NET form that calls a SQL Server Agent Job.  My problem is that I am disabling the button for 3 seconds once depressed so the job has time to finish.  If I hit the button several times in that 3 seconds, the button continues to function even though disabled....

What am I missing?

    Private Sub btnCallJob_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnCallJob.Click

        txtPkgStatus.Clear()
        txtPkgStatus.Refresh()
        Cursor = Cursors.WaitCursor
        BtnCallJob.Enabled = False

        'Call routine that runs sql server package and sleep 3 seconds.
        Call RunPackage2()

        Cursor = Cursors.Default
        BtnCallJob.Enabled = True

    End Sub

Thanks, Bill
0
Comment
Question by:FrancOIT
  • 7
  • 5
  • 2
  • +2
16 Comments
 
LVL 83

Expert Comment

by:CodeCruiser
ID: 37811639
Try adding a

Application.DoEvents

after

        BtnCallJob.Enabled = False

This is winforms right? If its ASP.NET then the button has to be disabled on client side using JavaScript.
0
 

Expert Comment

by:BlueMurder
ID: 37811678
you can try something like...

Do While Not myProcess.HasExited
                Application.DoEvents
Loop

Open in new window

0
 

Expert Comment

by:-Alan-
ID: 37811839
Your long job, RunPackage2, should be executed on a different thread. Once your task is done, you can then Invoke a method to re-enable the button. I would execute a method using the ThreadPool class to queue a task. In your method, call your RunPackage2 method, and then Invoke to re-enable the button.
0
 

Author Comment

by:FrancOIT
ID: 37811869
I actually had the Application.DoEvents after the BtnCallJob.Enabled = False but took it out because I didn't think it was doing anything.  After putting it back in, I discovered that if I hit the button 4 or 5 times, the click event seems to only be happening 2 times now.  SO it's better but still not correct.
0
 

Author Comment

by:FrancOIT
ID: 37811910
I will have to look into calling the Threadpool Class.  I've never done that before as I don't do much VB.NET programming.  I used to do some VB6 programming though, years ago.  I am a SQL DBA.
0
 
LVL 85

Accepted Solution

by:
Mike Tomlinson earned 30 total points
ID: 37811933
Call DoEvents() immediately BEFORE you set Enabled() to TRUE:
    Private Sub btnCallJob_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnCallJob.Click
        txtPkgStatus.Clear()
        txtPkgStatus.Refresh()
        Cursor = Cursors.WaitCursor
        BtnCallJob.Enabled = False

        'Call routine that runs sql server package and sleep 3 seconds.
        Call RunPackage2()

        Cursor = Cursors.Default
        Application.DoEvents()
        BtnCallJob.Enabled = True
    End Sub

Open in new window

0
 
LVL 85

Expert Comment

by:Mike Tomlinson
ID: 37811941
*I agree with the threading comments though.  You can place a BackgroundWorker() control on your form and use that for easy threading.
0
 

Author Closing Comment

by:FrancOIT
ID: 37811953
Thanks.  This fixed the problem.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 

Author Comment

by:FrancOIT
ID: 37811960
Sorry, I probably should have given points to that solution as well.  I haven't used EE much.  How do you determine how many points to assign a solution?
0
 

Expert Comment

by:-Alan-
ID: 37811979
Here is the solution in VB to your problem. What it demonstrates is that you should run your task on a different thread then the UI thread. Then when it is finished you can call the UI thread to re-enable the button.


Imports System
Imports System.Threading

Public Class Form1

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ' first disable your button
        Button1.Enabled = False

        'you need to run your long process on a different thread
        'the current thread from button1_click is the UI thread
        'it controls the GUI, and if you do anything too long on
        'the UI thread the GUI will not function properly

        ' queue the long task to the thread pool
        ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf DoMyTask))
    End Sub
    ' this is what the thread runs it calls your task,
    ' then asks the UI thread to renable the button
    Private Sub DoMyTask(o As Object)
        RunPackage2()

        ' renable button, anything that manipulates controls
        ' must be execute on the UI thread (use Invoke)
        Invoke(New ThreadStart(AddressOf EnableButton))
    End Sub

    ' this represents your long task
    Private Sub RunPackage2()
        System.Threading.Thread.Sleep(3000)
    End Sub

    ' renables the button
    Private Sub EnableButton()
        Button1.Enabled = True
    End Sub

End Class
0
 

Expert Comment

by:-Alan-
ID: 37811984
Calling DoEvents is bad practice!
0
 

Author Comment

by:FrancOIT
ID: 37811999
Alan, So how do I give you points, now that I already said that the DoEvents fixed my problem?  

Thanks a LOT for your input.
0
 

Expert Comment

by:-Alan-
ID: 37812012
I dunno! This was my very first post to EE!
0
 

Author Comment

by:FrancOIT
ID: 37812017
Geez.  I really appreciate your help.
0
 

Expert Comment

by:-Alan-
ID: 37812032
Another good point about my solution. Your GUI will lockup completely if you don't do it on another thread. With my solution you can still interact with other parts of the interface (if you don't want this disable the whole form) and move the dialog around
0
 

Author Comment

by:FrancOIT
ID: 37812053
Thanks!  Again, I'm not an expert .Net programmer.  I'm just writing a front end for one of our staff to call a SQL Agent job (that runs an SSIS package).
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

For those of you who don't follow the news, or just happen to live under rocks, Microsoft Research released a beta SDK (http://www.microsoft.com/en-us/download/details.aspx?id=27876) for the Xbox 360 Kinect. If you don't know what a Kinect is (http:…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now