@Uyen Nguyen , Welcome to Microsoft Q&A, Based on your description, you want to make a countdown timer and hope that it will contine when the form is closed.
I make some steps and code example. You could check if it works for you.
First, I make a countdown Timer from the answer.
Second, I add the following settings in the winform.
Third, I used FormClosing event to save some information to the settings.
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if(timer.IsRunnign)
{
Properties.Settings.Default.lefttime = label1.Text;
Properties.Settings.Default.Isrunning = true;
Properties.Settings.Default.closedtime=DateTime.Now;
Properties.Settings.Default.Save();
}
}
Fourth, I used Form1_Load event to read the information.
private void Form1_Load(object sender, EventArgs e)
{
if (Properties.Settings.Default.Isrunning== true)
{
string lefttime = Properties.Settings.Default.lefttime;
TimeSpan time1=TimeSpan.ParseExact(lefttime, @"mm\:ss", CultureInfo.CurrentCulture);
DateTime closedtime = Properties.Settings.Default.closedtime;
TimeSpan passedtime = DateTime.Now - closedtime;
var t = time1.Subtract(passedtime);
label1.Text=t.ToString(@"mm\:ss");
timer.SetTime(t.Minutes, t.Seconds);
timer.Start();
timer.TimeChanged += () => { label1.Text = timer.TimeLeftStr; };
// show messageBox on timer = 00:00.000
timer.CountDownFinished += () => { timer.Stop(); MessageBox.Show("Timer finished the work!"); };
//timer step. By default is 1 second
timer.StepMs = 1; // for nice milliseconds time switch
}
else
{
//set to 5 mins
timer.SetTime(5, 0);
//update label text
timer.TimeChanged += () => { label1.Text = timer.TimeLeftStr; };
// show messageBox on timer = 00:00.000
timer.CountDownFinished += () => { timer.Stop(); MessageBox.Show("Timer finished the work!"); };
//timer step. By default is 1 second
timer.StepMs = 1; // for nice milliseconds time switch
}
}
Finally, Please set the properties when we click the stop button.
Completed code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
CountDownTimer timer = new CountDownTimer();
private void Form1_Load(object sender, EventArgs e)
{
if (Properties.Settings.Default.Isrunning== true)
{
string lefttime = Properties.Settings.Default.lefttime;
TimeSpan time1=TimeSpan.ParseExact(lefttime, @"mm\:ss", CultureInfo.CurrentCulture);
DateTime closedtime = Properties.Settings.Default.closedtime;
TimeSpan passedtime = DateTime.Now - closedtime;
var t = time1.Subtract(passedtime);
label1.Text=t.ToString(@"mm\:ss");
timer.SetTime(t.Minutes, t.Seconds);
timer.Start();
timer.TimeChanged += () => { label1.Text = timer.TimeLeftStr; };
// show messageBox on timer = 00:00.000
timer.CountDownFinished += () => { timer.Stop(); MessageBox.Show("Timer finished the work!"); };
//timer step. By default is 1 second
timer.StepMs = 1; // for nice milliseconds time switch
}
else
{
//set to 5 mins
timer.SetTime(5, 0);
//update label text
timer.TimeChanged += () => { label1.Text = timer.TimeLeftStr; };
// show messageBox on timer = 00:00.000
timer.CountDownFinished += () => { timer.Stop(); MessageBox.Show("Timer finished the work!"); };
//timer step. By default is 1 second
timer.StepMs = 1; // for nice milliseconds time switch
Console.WriteLine(Properties.Settings.Default.lefttime);
}
}
private void button1_Click(object sender, EventArgs e)
{
timer.Start();
}
private void button2_Click(object sender, EventArgs e)
{
timer.Pause();
}
private void button3_Click(object sender, EventArgs e)
{
timer.Stop();
timer.Dispose();
Properties.Settings.Default.lefttime = "";
Properties.Settings.Default.Isrunning = false;
Properties.Settings.Default.closedtime = DateTime.Now;
Properties.Settings.Default.Save();
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if(timer.IsRunnign)
{
Properties.Settings.Default.lefttime = label1.Text;
Properties.Settings.Default.Isrunning = true;
Properties.Settings.Default.closedtime=DateTime.Now;
Properties.Settings.Default.Save();
}
}
}
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();
}
Tested result:
Hope this could help you.
Best Regards,
Jack
If the answer is the right solution, please click "Accept Answer" and upvote it.If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.