私には2つの形式Form1
とがありForm2
ます。Form1
しばらくの間(たとえば5分)表示してから非表示にしForm2
てさらに5分間表示Form2
してから、非表示にしてから表示する必要がありForm1
ます...
C ++ / CLIまたはC#でそれを行うにはどうすればよいですか?
私には2つの形式Form1
とがありForm2
ます。Form1
しばらくの間(たとえば5分)表示してから非表示にしForm2
てさらに5分間表示Form2
してから、非表示にしてから表示する必要がありForm1
ます...
C ++ / CLIまたはC#でそれを行うにはどうすればよいですか?
タイマーコントロールを使用します。これにより、実行間隔(この場合は5分)を設定できます。
頭のてっぺんから、私はおそらくこのようなことをするでしょう(C#の例が提供されています)
using System;
using System.Timers;
using System.Windows.Forms;
public class SwitchForms : IDisposable
{
private Form Form1 { get; set; }
private Form Form2 { get; set; }
private System.Timers.Timer VisibilityTimer { get; set; }
public SwitchForms(Form form1, Form form2, double hideMinutes)
{
Form1 = form1;
Form2 = form2;
VisibilityTimer = new System.Timers.Timer(hideMinutes * 60.0 * 1000.0);
VisibilityTimer.Elapsed += VisibilityTimer_Elapsed;
VisibilityTimer.Enabled = true;
//Could also consider subscribing to the close events of both forms here to disable the Timer
Form1.Invoke(new MethodInvoker(() => Form1.Show()));
Form2.Invoke(new MethodInvoker(() => Form2.Hide()));
}
private void VisibilityTimer_Elapsed(object source, ElapsedEventArgs e)
{
if(Form1 == null || Form2 == null)
{
VisibilityTimer.Enabled = false;
return;
}
if (Form1.IsDisposed || Form2.IsDisposed)
{
VisibilityTimer.Enabled = false;
Form1 = null;
Form2 = null;
}
else
{
Form1.Invoke(new MethodInvoker(() => { if(Form1.Visible) { Form1.Hide(); } else {Form1.Show();} }));
Form2.Invoke(new MethodInvoker(() => { if (Form2.Visible) { Form2.Hide(); } else { Form2.Show(); } }));
}
}
public void Dispose()
{
VisibilityTimer.Enabled = false;
VisibilityTimer.Dispose();
}
}
}
使用法では、Form1とForm2を作成するときに、Form1 / Form2のフィールドの1つにこれへの参照を保持でき、Form1/Form2を閉じるときにそれを破棄するだけです。
例:次のようなもの
public partial class Form1 : Form
{
private Form OtherForm { get; set; }
private SwitchForms FormSwitcher { get; set; }
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
OtherForm = new Form();
OtherForm.Text = "Other Form";
OtherForm.Show();
OtherForm.Closed += OtherForm_Closed;
FormSwitcher = new SwitchForms(this, OtherForm, 5.0);
}
void OtherForm_Closed(object sender, EventArgs e)
{
Show();
//Application.Exit(); //Could also consider closing the app if the other window is closed
}
}
注意すべき点がいくつかあります。
Form.Invoke の使用タイマーは基本的に別のスレッドで実行されているため、フォームのInvokeメソッドを使用することが重要です。そうしないと、クロススレッド例外が発生します。
潜在的な競合状態 時間間隔が非常に短い場合、経過したイベントが複数回発生する可能性があります。これはユーザーエクスペリエンスの観点からはばかげたことですが、重要な問題は、Form2が閉じられた後にTimer_Elapsedイベントが連続してすばやく呼び出された場合、null参照例外が発生する可能性があることです。Timer_Elapsedイベントが呼び出されている間にアプリがシャットダウンしている場合も、同じことが起こる可能性があります。ここで行う最善の方法は、アプリが閉じる前にタイマーを削除できるように、SwitchFormsクラスを破棄する(またはStopメソッドを追加する)ことです。
次に、たとえば、スタートアップクラスにSwitchFormsを配置することもできますが、Form1とForm2がまだ破棄されていないことなどを確認するために、特に注意する必要があります。
簡単にするために、SwitchFormsのコードをForm1またはForm2のいずれかに埋め込むこともできます。また、Form1またはForm2のいずれかが個別に閉じられた場合に何が起こるかについても考慮する必要があります。そうしないと、時限イベントによって例外がスローされます。
私の例では、Form2が閉じている場合はForm1を再表示し、Form1が閉じている場合はアプリを終了します。