Question

I have a windows form application that will open other forms, but will only display the forms for a few seconds (user configurable). I would normally do something like threading.thread.sleep(n), however when doing this the forms controls do not load only the white background shows, and I have also been reading that this isnt the best practice for what I am after as user input will not be actioned until the thread wakes up.

I have come across people using System.Timers.Timer(n), but I am struggling to get this to work for me, the form will only open and close straight away (you can only see a flash as the form opens then closes).

The code that I am using is:

Private Shared tmr As New System.Timers.Timer    
aForm.Show()
tmr = New System.Timers.Timer(aSleep * 60 * 60)
tmr.Enabled = True

aForm.Close()

This is all contained within a Private sub that passes the form and the defined run time.

My intention is to have the main application running from the task bar, which then calls one of the forms that will display for a defined period of time, close the form, then call another one of the forms.

Is any able to point me in the right direction for why the form opens then closes without seeing through the defined run time (I have been testing with 10 seconds), or is there a better way of doing what I am seeking?

Your help is greatly appreciated.

Matt

Was it helpful?

Solution

the docs say there's an Elapsed event handler that gets called when the time elapses. You would close the form in the handler:

http://msdn.microsoft.com/en-us/library/system.timers.timer%28VS.85%29.aspx

I just wrote a little example that shows what you would need to do at:

http://www.antiyes.com/close-form-after-10-seconds

Below is the relevant code, the full solution can be downloaded from the article.

Form 1 code

Public Class Form1

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim frm2 As New Form2()
        frm2.ShowDialog()
    End Sub

End Class

Form 2 code

Imports System.Timers

Public Class Form2

    Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
        MyBase.OnLoad(e)
        Dim tmr As New System.Timers.Timer()
        tmr.Interval = 5000
        tmr.Enabled = True
        tmr.Start()
        AddHandler tmr.Elapsed, AddressOf OnTimedEvent
    End Sub

    Private Delegate Sub CloseFormCallback()

    Private Sub CloseForm()
        If InvokeRequired Then
            Dim d As New CloseFormCallback(AddressOf CloseForm)
            Invoke(d, Nothing)
        Else
            Close()
        End If
    End Sub

    Private Sub OnTimedEvent(ByVal sender As Object, ByVal e As ElapsedEventArgs)
        CloseForm()
    End Sub

End Class

Of course for this code to work you'd need forms setup with the buttons.

OTHER TIPS

Your code sets a timer then immediately closes the form. The closing must be done when the timer event fires.

I think I can expand on Jonathan's answer a bit.

On the form that you wish to display for a given amount of time, add a timer (in this example the timer is named Timer1...Timers can be found in the toolbax, just drag it onto the form)

To have the form close after it has been displayed for a given amount of time start the timer in the onload method of the form:

Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    'Do initialization stuff for your form...
    'Start your timer last.
    Timer1.Start()
End Sub

This will start your timer. When the preset time elapses, the tick event will fire. In this event place your form closing code:

Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    'Close the form after 1 tick.
    Me.Close()
End Sub

To change how much time should elapse before the timer ticks, change the timer interval property.

'Changing the time from outside the Form1 class...
Form2.Timer1.Interval = 2000 '2 seconds, the interval is in milliseconds.

Full code, form1 has a button that sets the timer interval and then opens form2.

Public Class Form1
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Form2.Timer1.Interval = 2000
        Form2.Show()
    End Sub
End Class


Public Class Form2
    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        'Do initialization stuff for your form...
        'Start your timer last.
        Timer1.Start()
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Me.Close()
    End Sub
End Class

I hope this helps, let me know if I can restate anything in a more clear fashion :-)

Just stick a time component on the form and enable it. In the tick event handler, determine how long since the form opened and if the intended period has elapses, close the form.

By allowing the Form_Load handle to return while you wait for the Tick event, the form is allowed to paint and do everything else it normally would.

While you could create the time from code as you are doing, I'm not sure why you would. And you definitely need to set a handler for the Tick event for it to do any good.

A real simple way of opening a form for a set time (and in this example) will skip timer if frmTemperatureStatus is closed. I'm opening frmTemperatureStatus as a normal form not as a dialog otherwise the code jumps to this form and doesn't return until the form is closed. The DoEvents keeps frmTemperatureStatus responsive (Note: frmTemperatureStatus will keep losing focus if you test code line by line as focus keeps going back to Visual Studio).

            timeIncubation_End_Time = Now.AddMinutes(1)
            Me.Enabled = False
            frmTemperature_Status.Show()

            Do While frmTemperature_Status.Visible And timeIncubation_End_Time > Now
                Application.DoEvents()
                Threading.Thread.Sleep(100)
            Loop
            frmTemperature_Status.Close() ' This line doesn't cause an error if the form is already closed
            Me.Enabled = True
            MsgBox("End of dialog test")
Public Class Form1
    Dim second As Integer

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Timer1.Interval = 1000
        Timer1.Start() 'Timer starts functioning
    End Sub

    Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
        Label1.Text = DateTime.Now.ToString

        second = second + 1
        If second >= 10 Then
            Timer1.Stop() 'Timer stops functioning
            Me.Close()
            MsgBox("Timer Stopped....")
        End If

    End Sub

End Class
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top