假设我有两种形式Form1
和Form2
. 我需要显示Form1
一段时间(比如 5 分钟),然后隐藏它并再显示Form2
5 分钟,然后隐藏Form2
然后显示Form1
,依此类推......
如何在 C++/CLI 或 C# 中做到这一点?
假设我有两种形式Form1
和Form2
. 我需要显示Form1
一段时间(比如 5 分钟),然后隐藏它并再显示Form2
5 分钟,然后隐藏Form2
然后显示Form1
,依此类推......
如何在 C++/CLI 或 C# 中做到这一点?
使用Timer 控件。它使您能够设置执行间隔,在本例中为 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的其中一个字段中持有对this的引用,当你关闭Form1/Form2时,只需dispose即可。
例如:
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 事件 - 可能会获得空引用异常。如果应用程序在调用 Timer_Elapsed 事件时关闭,则可能会发生同样的情况 - 最好的办法是处理 SwitchForms 类(或添加一个 Stop 方法),以便您可以在应用程序关闭之前摆脱计时器。
例如,我还可以将 SwitchForms 放在我的启动类中,尽管我必须格外小心,然后检查 Form1 和 Form2 是否已经被处理等等。
为简单起见,您还可以将 SwitchForms 的代码嵌入到 Form1 或 Form2 中。您还需要考虑如果 Form1 或 Form2 独立关闭会发生什么,否则定时事件将引发异常。
在我的示例中,如果 Form2 关闭,我只是重新显示 Form1,如果 Form1 关闭,则应用程序退出。