tags:

views:

125

answers:

3

I'm coding a splash screen in VB.Net that displays for 3 seconds then shows a login screen. But the splash shows up even when login shows and I have told the splash to hide. Here is my code:

    Public Class frmSplash

    Private Sub frmSplash_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Show()
        System.Threading.Thread.Sleep(3000)
        Me.Hide()
        frmLogin.Show()
    End Sub
End Class
+1  A: 

Calling Thread.Sleep in the UI thread will freeze your program.

Also, the Load event fires before the form is shown, so you're calling Hide before the form is shown in the first place.

You need to add a Timer component to the form, set its Interval to 3000, and call Close in its Tick event. Then, call the timer's Start method in the forms Shown event.

SLaks
It is my understanding that if you place `.Show` in your Load event, it will show before the end of the load event. But perhaps it is better if the asker uses the `Shown` event instead, which is fired after the form is shown.
Abel
You have a point. However, no Windows messages will be processed during the `Sleep` call, so the form won't be painted, and probably wouldn't be visible at all.
SLaks
Alternatively, using Application.DoEvents() could work if you could get it to fire off while it is paused.
Cyclone
The `Shown` event is fired *after* painting. Which makes it ideal. But I fully agree that using Sleep here is not very suitable as it blocks everything else (and it won't be the first time I saw the Shown event with a partially drawn window). About `DoEvents` that works never while paused (no code is executed then), but when called before `Sleep` it should help.
Abel
**Never** call `Sleep` on the UI thread, even right after `DoEvents`. (Except maybe `Sleep(1)`)
SLaks
A: 

Your sleep statement is freezing your UI, try running it from another thread.

Cyclone
The correct thing to do here is use a WinForms timer; it will be more efficient than creating a thread.
SLaks
How would I use a timer to do this?
Mark Provan
@Mark: See my answer.
SLaks
But assuming he wants to use Sleep still, creating a new thread would be the most efficient way to do it like that. How is it more efficient to use a timer than a thread? I know it is a bit more confusing to use a new thread, but it still works.
Cyclone
Every thread you create involves a substantial amount of overhead.
SLaks
However, you're right that if he really wants to call `Sleep`, creating a thread (or using the ThreadPool) is the only way to do it.
SLaks
A: 

Thanks guys! This worked: Public Class frmSplash

Private Sub frmSplash_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    SplashTimer.Start()
End Sub

Private Sub SplashTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SplashTimer.Tick
    SplashTimer.Stop()
    frmLogin.Show()
    Me.Hide()
End Sub
End Class
Mark Provan