【问题标题】:C# timer won't tickC#计时器不会打勾
【发布时间】:2018-09-20 14:49:19
【问题描述】:

我有一个奇怪的问题... 在过去的几个小时里,我一直在发疯…… 我在我的 winform 代码(从工具栏)中输入的计时器不会打勾......

我的程序中有几个表单上有计时器,它们都工作正常...我尝试做完全相同的事情,它不会打勾... 我选择它,将它拖到一个表单上,启用它,设置间隔并处理滴答事件......并且没有任何反应...... 我什至尝试将诸如 messagebox.show 之类的随机代码放入 tick 事件中,以查看是否发生任何事情,但什么也没有! 正如我所说,我的程序中有几个计时器(在其他形式上,而不是我试图放置这个计时器的那个),它们都工作正常......

有什么建议吗?

提前致谢!

【问题讨论】:

  • 这是标准 Visual Studio 生成的计时器代码... this.timer1 = new System.Windows.Forms.Timer(this.components);私有 System.Windows.Forms.Timer timer1; this.timer1.Enabled = true; this.timer1.Interval = 1000; this.timer1.Tick += new System.EventHandler(this.timer1_Tick_1); private void timer1_Tick_1(object sender, EventArgs e) { MessageBox.Show("TIMER TICKS"); }
  • 您可以编辑原始帖子以添加代码。 (有时 cmets 会被隐藏)

标签: c# winforms timer


【解决方案1】:

我发现如果我从非 UI 线程停止计时器,然后重新启动它,我会丢失事件挂钩。

我不知道“正确”的答案是什么,但这对我来说效果很好:

public class BetterTimer : System.Windows.Forms.Timer
{
    public BetterTimer():base()        
    { base.Enabled = true; }

    public BetterTimer(System.ComponentModel.IContainer container) : base(container) 
    { base.Enabled = true; }

    private bool _Enabled;
    public override bool Enabled
    {
        get { return _Enabled; }
        set { _Enabled = value; }
    }

    protected override void OnTick(System.EventArgs e)
    { if (this.Enabled) base.OnTick(e); }
}

这种方法的三点:

1) 通过重写构造函数,我确保从一开始就启用基本计时器。

2) 通过覆盖“启用”,我永远不会让基本计时器被禁用,但界面不会改变。

3) 通过覆盖“OnTick”,我让覆盖的 Enabled 属性决定事件是否应该触发。

Start() 和 Stop() 通过分别为 Enabled 属性设置 true 和 false 来工作。

顺便说一句 - 有谁知道为什么当计时器从非 UI 线程停止/禁用时,事件永远不会触发(或断开连接?)?

【讨论】:

  • 这为我解决了。显然,始终在 UI 线程上停止/启动 System.Windows.Forms.Timer!
【解决方案2】:

不要在 .enabled 上启动 System.Windows.Forms.Timer 计时器...无论如何...我刚刚开始工作...我将 Visual Studio 生成的代码表单 WINFORMNAME.designer.cs 复制到 WINFORMNAME 。CS... 我不知道如何以及为什么,但它起作用了......

System.Windows.Forms.Timer timer = new System.Windows.Forms.Timer();
timer.Enabled = true;
timer.Interval = 1000; 
timer.Tick += new EventHandler(timer_Tick); 
        void timer_Tick(object sender, EventArgs e)
        {
//do something
        }

感谢大家的回答!

【讨论】:

    【解决方案3】:

    确保您通过调用timer1.Start()来启动它

    【讨论】:

    • .Enabled=true 应该足够了。
    • 是的,它“足够了”.. 事实上 .Start() 与设置为 True 的设置完全相同 :)
    • 如果 enabled = true 就够了,和调用.Start()一样,那为什么不行呢?他贴出来的VS生成的代码有this.timer1.Enabled=true;
    【解决方案4】:

    为了回答您的最后一个问题,不允许操作在另一个线程上创建的控件。您可以通过委托调用。

    【讨论】:

    • 在一个不相关但已解决的问题中,我不确定为什么我的 .Show() 或 .ShowDialog() 调用不起作用。我正在进行跨线程调用。这句话帮助我弄清楚了。谢谢。
    • 检查:TextBox.InvokeRequired 并调用如果为真解决了我的问题
    【解决方案5】:

    我以前遇到过这种情况。我在设置间隔之前启用了计时器。交换两条线使其工作。

    【讨论】:

      【解决方案6】:

      我遇到了和 Andrej 相同的问题,我尝试了几种在网上找到的解决方案。

      我的程序中的每个表格都有时间限制(倒计时),这是我解决它的方法:

      我使用了计算机工程解决方案。关掉再打开!! :)) 我的意思是我不知道为什么,但它有效!

      首先我从 .cs 和设计中删除了所有计时器 然后我在每个表单中添加了一个计时器,并为计时器和文本框输入了不同的名称,并一一编写了相同的代码。

      我只是使用了 timer.start() 和 Timer.stop()

      private void Form7_Load_1(object sender, EventArgs e)
          {
              timer7.Start();
          }
      
          int duration = 30;
      
          private void timer7_Tick(object sender, EventArgs e)
          {
              duration--;
              textBox7.Text = duration.ToString(); // to show the countdown 
      
              if (duration == 0)
              {
                  timer7.Stop();
                  MessageBox.Show("You ran out of time. Please go to the next page");
      
                  this.Hide();
                  Form8 f8 = new Form8();
                  f8.ShowDialog();
              }
          }
      

      希望对你有帮助

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-05
        相关资源
        最近更新 更多