【问题标题】:Alternating two forms for a while of time交替两种形式一段时间
【发布时间】:2012-09-06 06:03:56
【问题描述】:

假设我有两种形式 Form1Form2。我需要显示 Form1 一段时间(比如 5 分钟),然后隐藏它并显示 Form2 再显示 5 分钟,然后隐藏 Form2,然后显示 Form1 等等......

如何在 C++/CLI 或 C# 中做到这一点?

【问题讨论】:

    标签: c# winforms visual-studio-2010 c++-cli


    【解决方案1】:

    使用Timer control。它使您可以设置执行间隔,在本例中为 5 分钟。

    【讨论】:

      【解决方案2】:

      在我的脑海中,我可能会做这样的事情(提供 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
          }
      
        }
      

      有几点需要注意:

      1. Form.Invoke 的使用 由于计时器本质上是在单独的线程中运行,因此使用表单的 Invoke 方法很重要,否则您将获得跨线程异常。

      2. 潜在的竞争条件 如果时间间隔非常小,则 elapsed 事件可能会触发多次。尽管从用户体验的角度来看这是一件愚蠢的事情,但关键问题是如果在 Form2 关闭后快速连续调用 Timer_Elapsed 事件 - 可能会出现空引用异常。如果在调用 Timer_Elapsed 事件时应用程序正在关闭,则可能会发生同样的情况 - 最好的办法是 Dispose SwitchForms 类(或添加一个 Stop 方法),这样您就可以在应用程序关闭之前摆脱计时器。

      然后,我也可以将 SwitchForms 放在我的启动类中,尽管我必须格外小心,然后检查 Form1 和 Form2 是否已经被释放等等。

      为简单起见,您还可以将 SwitchForms 的代码嵌入到 Form1 或 Form2 中。您还需要考虑如果 Form1 或 Form2 独立关闭会发生什么,否则定时事件将引发异常。

      在我的示例中,如果 Form2 关闭,我只是重新显示 Form1,如果 Form1 关闭,则应用程序退出。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-11-14
        • 1970-01-01
        • 1970-01-01
        • 2013-05-15
        • 1970-01-01
        • 2011-09-28
        • 1970-01-01
        • 2018-01-19
        相关资源
        最近更新 更多