質問
他のフォームを開くWindowsフォームアプリケーションがありますが、数秒間のフォームのみを表示します(ユーザー構成可能)。私は通常、threading.thread.sleep(n)のようなことをしますが、これを行うと、フォームコントロールは白い背景の表示だけをロードしません。スレッドが目覚めるまで、入力はアクションされません。
System.timers.timer(n)を使用して人々に出くわしましたが、これを機能させるのに苦労しています。フォームはすぐに開閉します(フォームが開くと閉じるとフラッシュが表示されます) 。
私が使用しているコードは次のとおりです。
Private Shared tmr As New System.Timers.Timer
aForm.Show()
tmr = New System.Timers.Timer(aSleep * 60 * 60)
tmr.Enabled = True
aForm.Close()
これはすべて、フォームと定義された実行時間を通過するプライベートサブ内に含まれています。
私の意図は、メインアプリケーションをタスクバーから実行することです。これは、定義された期間に表示されるフォームの1つを呼び出し、フォームを閉じて、フォームの1つを呼び出すことです。
フォームが開く理由を正しい方向に向けることができる人は、定義された実行時間を見ずに閉じることができます(10秒でテストしています)、または私が求めていることをするより良い方法はありますか?
あなたの助けは大歓迎です。
マット
解決
ドキュメントは、時間が経過するときに呼び出される経過イベントハンドラーがあると言います。ハンドラーのフォームを閉じます:
http://msdn.microsoft.com/en-us/library/system.timers.timer%28vs.85%29.aspx
私はあなたがしなければならないことを示す小さな例を書きました:
http://www.antiyes.com/close-form-after-10秒
以下は関連するコードです。完全なソリューションは記事からダウンロードできます。
フォーム1コード
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
フォーム2コード
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
もちろん、このコードが機能するには、ボタンを使用してフォームセットアップが必要です。
他のヒント
コードはタイマーを設定し、すぐにフォームを閉じます。タイマーイベントが発射されたときに閉鎖を行う必要があります。
ジョナサンの答えを少し拡張できると思います。
特定の時間を表示したいフォームでは、タイマーを追加します(この例では、タイマーの名前はTimer1です...タイマーはツールバックスにあり、フォームにドラッグするだけです)
特定の時間のために表示された後にフォームを閉じるには、フォームのオンロード方法でタイマーを開始します。
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
'Close the form after 1 tick.
Me.Close()
End Sub
タイマーがチェックする前にどれくらいの時間が経過するかを変更するには、タイマー間隔プロパティを変更します。
'Changing the time from outside the Form1 class...
Form2.Timer1.Interval = 2000 '2 seconds, the interval is in milliseconds.
完全なコード、Form1には、タイマー間隔を設定し、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
これが役立つことを願っています、私がより明確な方法で何かを言い換えることができるかどうか教えてください:-)
フォームに時間コンポーネントを貼り付けて有効にしてください。ティックイベントハンドラーでは、フォームが開いてからどれくらいの期間、意図した期間が経過している場合は、フォームを閉じます。
ティックイベントを待つ間、Form_loadハンドルが返されるようにすることにより、フォームはペイントし、通常の他のすべてを実行できます。
あなたがしているようにコードから時間を作成することができますが、なぜそうなるのかはわかりません。そして、あなたは間違いなく、ティックイベントのためにハンドラーを設定する必要があります。
FRMTemperaturestatusが閉じられている場合、設定された時間(およびこの例では)のフォームを開く実際の簡単な方法(およびこの例)は、タイマーをスキップします。私はダイアログとしてではなく通常のフォームとしてfrmtemperaturestatusを開きます。そうしないと、コードがこのフォームにジャンプし、フォームが閉じるまで戻りません。 DoEventsは、Frmtemperaturestatusを応答し続けます(注:Frmtemperaturestatusは、フォーカスが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