【问题标题】:Adding controls to form using timers使用计时器向表单添加控件
【发布时间】:2015-02-02 09:12:59
【问题描述】:

所以我正在尝试向表单添加控件,并且我正在使用一种变通方法,因此我可以通过静态函数添加控件,我是这样做的:

Control c = this;
Button b = new Button();
//....
c.Controls.Add(b);

这行得通,所以我一直使用这种方法来添加控件。但是现在我用的是定时器,它不起作用

Control c = this;
Timer t = new Timer(500);
t.Elapsed += new ElapsedEventHandler(t_Elapsed);


public static void t_Elapsed(object sender, ElapsedEventArgs e)
{
Button b = new Button();
//...
c.Controls.Add(b);
}

t_Elapsed 函数运行,那里的代码正在执行,但 c.Controls.Add(b) 行不起作用。

【问题讨论】:

  • 不起作用是什么意思?

标签: c# timer controls


【解决方案1】:

您的代码存在一些问题:

  1. 既然您本来可以只使用非静态事件处理程序,为什么还要使用静态事件处理程序,然后使用变通方法来访问实例变量?

  2. 您使用的计时器类是System.Timers.Timer,还有几个不同的计时器类,它们的行为略有不同。比较可以找到here

当您以任何方式修改 UI 时,您必须从 UI 线程执行此操作。 System.Timers.Timer 可以在 UI 线程上调用事件处理程序,但前提是您提供了一个同步对象,即任何实现 ISynchronizeInvoke 接口的对象,例如Form.

如果this 引用Form 类的实例,您可以使用t.SynchronizingObject = this 设置同步对象。

【讨论】:

    【解决方案2】:

    您必须访问创建它们的线程上的控件。

    您的计时器已用事件在与 UI 不同的线程上触发,因此您需要将调用编组到 UI 线程。

    这可以通过Invoke来完成:

        void t_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            this.BeginInvoke((Action)delegate
            {
                Button b = new Button();
                c.Controls.Add(b);
            });
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-24
      • 2011-01-01
      • 1970-01-01
      相关资源
      最近更新 更多