【问题标题】:C# winform - Raise a personal event in Timer_tick eventC# winform - 在 Timer_tick 事件中引发个人事件
【发布时间】:2016-09-28 14:09:39
【问题描述】:

我创建了一个包含计时器的小类 CountDown 。

类很简单:接收时间目标,并使用计时器启动倒计时。

当达到目标时,我的个人事件触发:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CountDownWithEvent
{
    public delegate void countDownFinishEventHandler(Object sender, EventArgs e);
    class CountDown
    {
        private DateTime _target;
        private System.Windows.Forms.Timer _timer;
        System.TimeSpan _timeMissing;


        public event countDownFinishEventHandler CountDownFinish;

        public CountDown(DateTime targetTime)
        {
            this._target = targetTime;
            this._timer = new System.Windows.Forms.Timer();
            this._timeMissing = new TimeSpan();
        }

        public DateTime TargetTime
        {
            get;
        }

        public TimeSpan timeMissing
        {
            get;
        }

        public void CountDownStart()
        {
            _timer.Interval = 1000;
            _timer.Tick += new EventHandler(timer_tick);
            _timer.Start();
        }

        protected virtual void timer_tick(Object sender, EventArgs e)
        {
            //if (_timer.Tick != null)
            //{
            //}
            System.DateTime now = System.DateTime.Now;
            _timeMissing = _target.Subtract(now);
            if (!(timeMissing.TotalSeconds > 0))
            {
                _timer.Stop();
                if(CountDownFinish != null)
                {
                    EventArgs b = new EventArgs();
                    CountDownFinish(this, b);
                }
            }
        }


    }
}


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CountDownWithEvent
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            CountDown CountDown = new CountDown(new DateTime(2016, 05, 27, 14, 48, 00));
            CountDown.CountDownFinish += new countDownFinishEventHandler(onCountDown);
            CountDown.CountDownStart();
        }

        private void onCountDown(Object sender, EventArgs e)
        {
            MessageBox.Show("time expired! ");
        }
    }
}

我使用EventArgs,而不是写派生类,因为我不需要事件的任何特殊信息(理解,参数e

现在我的情况有点不寻常:

protected virtual void timer_tick(Object sender, EventArgs e)
    {
        //if (_timer.Tick != null)
        //{
        //}
        System.DateTime now = System.DateTime.Now;
        _timeMissing = _target.Subtract(now);
        if (!(timeMissing.TotalSeconds > 0))
        {
            _timer.Stop();
            if(CountDownFinish != null)
            {
                EventArgs b = new EventArgs();
                CountDownFinish(this, b);
            }
        }
    }

当我调用CountdownFinish(this,e); 时,e 参数指的是 timer_tick 通过 EventArgs 计时器不一致 所以我不知道该怎么做???

其实我已经实例化了新的EventArgs b

            EventArgs b = new EventArgs();
            CountDownFinish(this, b);

但我不知道这是否是正确的道路

现在我是另一个问题:

我想在标签中看到距离目标还剩多少时间。并将其刷新到任何 timer_tick。 而我想保持程序图形的定时器逻辑分开.. 我该怎么做?

非常感谢您的理解和帮助! (抱歉英语不好,不是我的语言:))

【问题讨论】:

  • 如果您解决了问题,请不要在同一个帖子中添加另一个问题,而是提出新问题。
  • 谢谢提问..但我还没有解决...第一个是疑问..第二个是问题
  • 1- 要提供一个值以用于没有事件数据的事件,请使用 EventArgs.Empty2- 创建TimeLeft 属性,该属性显示完成的剩余时间并在计时器滴答事件中减少它。同时创建TimeLeftChanged 事件,当TimeLeft 改变时触发。
  • @RezaAghaei 谢谢。如果我创建一个减少的属性......如何刷新标签?!这是我想念的段落(我希望克服我的困难)..而CountDownForm 是一个单独的类...Also create TimeLeftChanged event which fires when TimeLeft changes 使用此解决方案如何将数据传递给标签?在CountDown类型标签中创建一个成员类?
  • 在表单中订阅组件的TimeLeftChanged事件,并在处理事件的方法中将标签文本设置为组件TimeLeft属性的值。

标签: c# winforms events timer event-handling


【解决方案1】:

@Reza Aghaei

好的,这是我的解决方案.. 你怎么看?!

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace EventsTry
{
    public delegate void countDownFinishEventHandler(Object sender, EventArgs e);
    public delegate void TimeLeftChangedEventHandler(Object sender, TimeLeftDateEventArgs e);
    class CountDown
    {
        private DateTime _target;
        private System.Windows.Forms.Timer _timer;
        System.TimeSpan _timeMissing;

        public event countDownFinishEventHandler CountDownFinish;
        public event TimeLeftChangedEventHandler TimeLeftChanged;

        public CountDown(DateTime targetTime)
        {
            this._target = targetTime;
            this._timer = new System.Windows.Forms.Timer();
            this._timeMissing = new TimeSpan();
        }

        public DateTime TargetTime
        {
            get { return this._target; }
        }

        public TimeSpan timeMissing
        {
            get { return this._timeMissing; }
        }

        public void CountDownStart()
        {
            _timer.Interval = 1000;
            _timer.Tick += new EventHandler(timer_tick);
            _timer.Start();
        }

        protected virtual void timer_tick(Object sender, EventArgs e)
        {
            System.DateTime now = System.DateTime.Now;
            _timeMissing = _target.Subtract(now);


            if (!(timeMissing.TotalSeconds > 0))
            {
                _timer.Stop();


                if (CountDownFinish != null)
                {
                    CountDownFinish(this, EventArgs.Empty);
                }
            }
            else
            {
                if (TimeLeftChanged != null)
                {
                    TimeLeftChanged(this, new TimeLeftDateEventArgs(timeMissing));
                }
            }
        }

    }

    public class TimeLeftDateEventArgs : EventArgs
    {
        private int _hours;
        private int _minutes;
        private int _seconds;

        public TimeLeftDateEventArgs(TimeSpan timespan)
        {
            _hours = timespan.Hours;
            _minutes = timespan.Minutes;
            _seconds = timespan.Seconds;

        }

        public int Hours
        { get { return this._hours; } }

        public int Minutes
        { get { return this._minutes; } }

        public int Seconds
        { get { return this._seconds; } }

    }


}

表单类

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace EventsTry
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            CountDown CountDown = new CountDown(new DateTime(2016,06,01,11,35,00));
            CountDown.CountDownFinish += new countDownFinishEventHandler(onCountDown);
            CountDown.TimeLeftChanged += new TimeLeftChangedEventHandler(onTimeLeft);
            CountDown.CountDownStart();
        }

        private void onCountDown(Object sender, EventArgs e)
        {
            MessageBox.Show("time expired! ");
        }

        private void onTimeLeft(Object sender, TimeLeftDateEventArgs e)
        {
            label1.Text = e.Hours + ":" + e.Minutes + ":" + e.Seconds;
        }
    }
}

我知道委托countDownFinishEventHandler 等于EventHandler。 我并没有因为懒惰而改变。

我想对TimeLeftDateEventArgs 使用内部类,但公共委托是CountDown 类的外部类,然后委托无法访问TimeLeftDateEventArgs

2- 创建 TimeLeft 属性,该属性显示完成的剩余时间并在计时器滴答事件中减少它。

你的意思是这个解决方案?还是其他方式!?

【讨论】:

  • 你快到了。要创建自定义事件,请使用 such solution。但不要使用EventHandler,而是使用public event EventHandler<TimeLeftDateEventArgs> TimeLeftChanged;。此外,如果您的 TimeLeftChangedEventArgs 包含足够的信息,则您不需要该类的任何其他属性。我在 cmets 中提到的属性是用于获取您当前在事件 arg 中拥有的信息,您可以使用主题显示在标签上。
  • 所以为了让答案更有用,编辑答案并以正确的方式添加事件。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-24
  • 1970-01-01
  • 2018-07-16
  • 2016-03-20
  • 2010-11-23
相关资源
最近更新 更多