【问题标题】:How to access programmatically created timer controls?如何访问以编程方式创建的计时器控件?
【发布时间】:2014-09-11 10:36:28
【问题描述】:

在 WinForms (C#) 应用程序中,我在运行时创建了几个自定义控件。这些自定义控件称为 JobTimers 并继承/扩展标准控件 Timer。

public class JobTimer : System.Windows.Forms.Timer
{
    private int IntJobID;
    public int JobID
    {
        get{return IntJobID;}
        set{IntJobID = value;}
    }
}

public static void CreateTimer(int JobID) 
{
    JobTimer ControlJobTimer = new JobTimer();
    ControlJobTimer.Enabled = true;
    ControlJobTimer.JobID = JobID;
    ControlJobTimer.Interval = 30000;
    ControlJobTimer.Tick += new EventHandler(JobTimer_Tick);
    ControlJobTimer.Start(); 
}

类似于我们如何在表单上查询标准或自定义控件的集合 - 我们可以访问/查询这些自定义 JobTimer 控件的集合吗?

注意:出现此问题的原因是我没有看到这些控件停靠/放置在任何表单中,因此仅存在于程序的内存中。同样在停止/退出应用程序时,这些控件也消失了。

换句话说,如何获得应用程序中所有计时器的列表以及对其属性的访问权限?

【问题讨论】:

  • 您可以通过创建List<Timer> 来获取计时器列表。踢开的门怎么样 ;) 你现在所拥有的并没有给你任何体面的方法来获得对计时器对象的引用。你有一个,但它只是一个局部变量,在 CreateTimer() 返回后是奇闻趣事。剩下的就是 Tick 事件处理程序中的 sender 参数。使用列表。

标签: c# winforms timer custom-controls programmatically-created


【解决方案1】:
    public static List<JobTimer> _timers;

    public class JobTimer : System.Windows.Forms.Timer
    {
        private int IntJobID;
        public int JobID
        {
            get { return IntJobID; }
            set { IntJobID = value; }
        }
    }

    public static void CreateTimer(int JobID)
    {
        if (_timers == null)
        {
            _timers = new List<JobTimer>();
        }
        JobTimer ControlJobTimer = new JobTimer();
        ControlJobTimer.Enabled = true;
        ControlJobTimer.JobID = JobID;
        ControlJobTimer.Interval = 30000;
        ControlJobTimer.Tick += new EventHandler(JobTimer_Tick);
        ControlJobTimer.Start();
        _timers.Add(ControlJobTimer);
    }

然后你可以访问全局列表_timers,所有创建的jobtimer实例都会被添加到那里

【讨论】:

  • 感谢您的解决方案。您能否对这部分有所了解: if (_timers == null) { _timers = new List(); }
  • 这只是创建列表的实例,如果_timers没有被分配那么你必须创建一个新的列表,否则它已经创建并且什么都不做。您也可以在程序开始时执行此操作,那么您不需要 CreateTimer 中的 if 语句。例如。您可以在 form_load 事件中创建实例 (msdn.microsoft.com/en-us//library/…) --> _timers = new List();
  • @user1519979 只是好奇为什么在声明列表时不实例化它?
【解决方案2】:

这段代码有异味。从 Timers 派生的自定义控件是实现您想要的非常昂贵的方法。您可以使用线程、后台工作人员、订阅/发布模型,这会更优化。

我们可以访问/查询这些自定义 JobTimer 控件的集合吗?

很简单,当你声明 JobTimers 在父表单中保持对它们的访问时,例如:

List<JobTimer> jobTimers = new List<JobTimer>();

【讨论】:

  • 感谢您的解决方案。当我精通这些领域时,我会开始使用线程、后台工作人员等...... :)
  • 好的,答应我你会努力尝试background workerexample。我现在给 +5 分,以便您可以在 Stack Overflow 上投票,以期作为回报,您会提供更好的解决方案。
  • 你打赌..!!! :) 我已经在阅读有关后台工作人员的信息,并且一定会在即将开展的项目中雇用他们。感谢您的指导。
【解决方案3】:

正如其他人已经说过的,您必须自己保存并保持安全创建的计时器。没有AllTimers 集合,所以你必须创建和管理一个。

子类化Timer 是个坏主意。这里可能是更合适且易于扩展的版本:

using System.Windows.Forms;

public class JobTimer
{
    public Timer Timer {get; set;}
    public string ID {get; set;}
}

public List<JobTimer> _timers = new List<JobTimer>();

public static void CreateTimer(int id) 
{
    var timer = new Timer() { Interval = 30000 };
    var job = new JobTimer() { Timer = timer, ID = id };
    _timers.Add(job);
    timer.Tick += JobTimer_Tick;
    timer.Start(); 
}

public static void DisposeTimers()
{
    foreach(var timer in _timers)
        timer.Dispose();
}

【讨论】:

  • 感谢您的解决方案。创建继承类是我知道的添加自定义属性的唯一方法。我也试试看。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-11-21
  • 2017-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多