alanlittle
alanlittle

Reputation: 470

Animate Button Movement

I'm trying to animate the movement of two buttons on a Windows Form in VB.Net. The form is loaded with ShowDialog() from the main form. I have the following code:

Private Sub MoveButtons(sender As Object, e As EventArgs) Handles picLogo.Click
    Dim SLoc As Point = btnSearch.Location
    Dim CLoc As Point = btnCancel.Location

    txtSearch.Enabled = False
    txtSearch.Visible = False
    btnSearch.Text = "Add"

    For idx As Integer = 1 To 36
        SLoc.Y -= 1
        btnSearch.Location = SLoc
        CLoc.Y -= 1
        btnCancel.Location = CLoc
        Thread.Sleep(5)
    Next
End Sub

I originally coded it using the Top property, but the result is the same. The Cancel button slides up as expected, but the Search/Add button simply disappears from the bottom up, then jumps up to the proper position. This happens regardless of whether I change the button text. Apart from the obvious Location and Text properties, the two buttons are identical, except the Cancel button has DialogResult set to DialogResult.Cancel.

Form screenshots

Upvotes: 0

Views: 190

Answers (1)

djv
djv

Reputation: 15774

You aren't giving the UI any time to update itself properly. Although that Thread.Sleep(5) is vital to the timing of your loop, it is also putting the UI thread to sleep. You don't want to do that.

So an easy but uninformed fix is to put Application.DoEvents() in the loop. This will allow the UI to update itself. This should make your code work...

...
Application.DoEvents()
Thread.Sleep(5)

But if you do enough of this type of thing, you will notice your UI slows down. It will give a bad feel to the application. You never want to put the UI thread to sleep.

What you should do is take all the non-ui stuff off the UI. You can create a thread and put it there. Inside the thread, however, you'd need to Invoke any UI calls back to the UI. Here's how

Private Sub MoveButtons(sender As Object, e As EventArgs) Handles picLogo.Click
    txtSearch.Enabled = False
    txtSearch.Visible = False
    btnSearch.Text = "Add"
    Dim moveThread As New System.Threading.Thread(AddressOf moveButtonsSub)
    moveThread.Start()
End Sub

Private Sub moveButtonsSub()
    Dim SLoc As Point = btnSearch.Location
    Dim CLoc As Point = btnCancel.Location
    For idx As Integer = 1 To 36
        SLoc.Y -= 1
        CLoc.Y -= 1
        Me.Invoke(
            Sub()
                btnSearch.Location = SLoc
                btnCancel.Location = CLoc
            End Sub)
        Thread.Sleep(5)
    Next
End Sub

Upvotes: 1

Related Questions