Реализовать сброс таймера
Есть таймер, кнопка запуск\стоп и кнопка сброс, все традиционно. Но я не могу придумать как его сбросить.
using System;
using System.Windows.Forms;
namespace lab6
{
public partial class ChildForm : Form
{
DateTime date = DateTime.Now;
Timer timer = new Timer();
public ChildForm()
{
InitializeComponent();
}
private void tickTimer(object sender, EventArgs e)
{
long tick = DateTime.Now.Ticks - date.Ticks;
DateTime stopWatch = new DateTime();
stopWatch = stopWatch.AddTicks(tick);
label1.Text = String.Format("{0:HH:mm:ss:fff}", stopWatch);
}
private void button1_Click_1(object sender, EventArgs e) //это кнопка старт\стоп
{
timer.Enabled = !timer.Enabled;
timer.Interval = 1;
timer.Tick += new EventHandler(tickTimer);
button1.Text = timer.Enabled ? "Стоп" : "Старт";
}
private void button3_Click(object sender, EventArgs e)
{
//button3 это кнопка, отвечающая за сброс. Тут собственно метод нужон.
}
}
}
Ответы (2 шт):
Автор решения: aepot
→ Ссылка
У вас привязка идет к моменту запуска программы, немного странная реализация. Но велосипед можно не изобретать и использовать специально предназначенный для этого класс Stopwatch.
Поправил код:
using System.Diagnostics;
public partial class ChildForm : Form
{
Timer timer = new Timer();
Stopwatch stopWatch = new Stopwatch();
public ChildForm()
{
InitializeComponent();
// это надо сделать 1 раз, а не каждый раз, когда вы запускаете таймер.
// еще этот код лучше унести отсюда в обработчик события Form.Load
// потому что в конструкторе окна в целом опасно вставлять код
timer.Interval = 1;
timer.Tick += new EventHandler(tickTimer);
}
private void tickTimer(object sender, EventArgs e)
{
// вынес обновление текста таймера в отдельный метод
RefreshTimer();
}
private void RefreshTimer()
{
// мне не нравится эта реализация, возможно есть способ проще
// но код писал на коленке в блокноте, не мог тестировать
DateTime date = new DateTime(stopWatch.ElapsedTicks);
label1.Text = String.Format("{0:HH:mm:ss:fff}", date);
}
private void button1_Click_1(object sender, EventArgs e)
{
timer.Enabled = !timer.Enabled;
if (timer.Enabled)
stopWatch.Start();
else
stopWatch.Stop();
button1.Text = timer.Enabled ? "Стоп" : "Старт";
}
private void button3_Click(object sender, EventArgs e)
{
stopWatch.Reset();
RefreshTimer(); // и вот почему я вынес в отдельный метод
}
}
Рекомендация: называйте методы с большой буквы, а переменные и поля с маленькой.
Автор решения: Andrew
→ Ссылка
Пример использования моего таймера:
CountDownTimer timer = new CountDownTimer();//создаем инстанс
timer.SetTime(30,0); //выставляем на 30 минут
timer.StepMs = 33; //Выставляем шаг таймера (как часто вызывается TimeChanged)
//Подписываемся на событие TimeChanged и в нем обновляем значение лейбла
timer.TimeChanged += () => Label1.Text = timer.TimeLeftMsStr;
// Подписываемся на событие окончания таймера и реагируем на него сообщухой
timer.CountDownFinished += () => MessageBox.Show("Timer finished the work!");
timer.Start(); //стартуем
И не забываем вызвать Dispose(); когда таймер уже не нужен.
Сброс можно сделать по вызову метода reset() или restart()
Код самого таймера:
using System;
using System.Diagnostics;
using System.Windows.Forms;
public class CountDownTimer : IDisposable
{
public Stopwatch _stpWatch = new Stopwatch();
public Action TimeChanged;
public Action CountDownFinished;
public bool IsRunnign => timer.Enabled;
public int StepMs
{
get => timer.Interval;
set => timer.Interval = value;
}
private Timer timer = new Timer();
private TimeSpan _max = TimeSpan.FromMilliseconds(30000);
public TimeSpan TimeLeft => (_max.TotalMilliseconds - _stpWatch.ElapsedMilliseconds) > 0 ? TimeSpan.FromMilliseconds(_max.TotalMilliseconds - _stpWatch.ElapsedMilliseconds) : TimeSpan.FromMilliseconds(0);
private bool _mustStop => (_max.TotalMilliseconds - _stpWatch.ElapsedMilliseconds) < 0;
public string TimeLeftStr => TimeLeft.ToString(@"\mm\:ss");
public string TimeLeftMsStr => TimeLeft.ToString(@"mm\:ss\.fff");
private void TimerTick(object sender, EventArgs e)
{
TimeChanged?.Invoke();
if (_mustStop)
{
CountDownFinished?.Invoke();
_stpWatch.Stop();
timer.Enabled = false;
}
}
public CountDownTimer(int min, int sec)
{
SetTime(min, sec);
Init();
}
public CountDownTimer(TimeSpan ts)
{
SetTime(ts);
Init();
}
public CountDownTimer()
{
Init();
}
private void Init()
{
StepMs = 1000;
timer.Tick += new EventHandler(TimerTick);
}
public void SetTime(TimeSpan ts)
{
_max = ts;
TimeChanged?.Invoke();
}
public void SetTime(int min, int sec = 0) => SetTime(TimeSpan.FromSeconds(min * 60 + sec));
public void Start() {
timer.Start();
_stpWatch.Start();
}
public void Pause()
{
timer.Stop();
_stpWatch.Stop();
}
public void Stop()
{
Reset();
Pause();
}
public void Reset()
{
_stpWatch.Reset();
}
public void Restart()
{
_stpWatch.Reset();
timer.Start();
}
public void Dispose() => timer.Dispose();
}