Maurício Morhy
Maurício Morhy

Reputation: 97

Reset CountDown Timer

The timer does not start without the EventHandler (timerIdle_Tick):

timerIdle.Tick += new EventHandler(timerIdle_Tick);

Follow the timer code after your indication:

class Timers
{
    public static System.Windows.Forms.Label lblIdle;
    public static Timer timerIdle = new Timer();
    public static int segundo = 0;

    // TIMER IDLE
    public static void timerIdleOn()
    {
        segundo = 300;
        timerIdle.Interval = 1000;
        timerIdle.Start();
    }
    public static void timerIdleOff()
    {
        timerIdle.Stop();
    }

    public static void timerIdle_Tick(object sender, EventArgs e)
    {
        segundo--;

        if (segundo == 0)
        {
            timerIdle.Stop();
            dgView.addLinha(2, "config_Teste", "TIMER ACABOU", 0);
        }
        else
            dgView.addLinha(2, "config_Teste", TimeSpan.FromSeconds(segundo).ToString(@"mm\:ss"), 0);
    }
}

It follows where the timer is started, I don't use buttons, just one temporarily to test methods, it won't exist afterwards.

namespace HC
{
    public partial class frm_console : Form
    {
        public frm_console()
        {
            InitializeComponent();
            dgView.DataConsole = this.DataConsol;           
            Timers.timerIdleOn();
        }
    }
}

Upvotes: 0

Views: 903

Answers (3)

Idle_Mind
Idle_Mind

Reputation: 39152

This is more like what I'd expect to see. The Timer is being created and handled INSIDE the frm_console class. Note that all of the statics have been REMOVED:

public partial class frm_console : Form
{

    public int segundo = 300;
    public Timer timerIdle = new Timer();   
    
    public frm_console()
    {
        InitializeComponent();
        dgView.DataConsole = this.DataConsol;
        timerIdle.Interval = 1000; 
        timerIdle.Tick += new EventHandler(timerIdle_Tick);        
        timerIdle.Start();
    }
    
    private void btnReset_Click(object sender, EventArgs e)
    {
        segundo = 300; // reset to 5 minutes
        timerIdle.Start();
    }

    private void btnPauseResume_Click(object sender, EventArgs e)
    {
        if (timerIdle.Enabled)
        {
            timerIdle.Stop();
        }
        else if (segundo > 0)
        {
            timerIdle.Start();
        }
    }

    private void btnStop_Click(object sender, EventArgs e)
    {
        timerIdle.Stop();
    }   

    public void timerIdle_Tick(object sender, EventArgs e)
    {
        segundo--;
        
        if (segundo == 0)
        {
            timerIdle.Stop();
            dgView.addLinha(2, "config_Teste", "TIMER ACABOU", 0);
        }
        else
        {
            dgView.addLinha(2, "config_Teste", TimeSpan.FromSeconds(segundo).ToString(@"mm\:ss"), 0);
        }
    }
            
}

The methods beginning with "btn" are button click handlers, but they could be converted to regular methods. You should be able to understand what they're doing.

Upvotes: 1

Peter Duniho
Peter Duniho

Reputation: 70701

With respect to this:

timerIdle.Stop();
timerIdle.Start();

The Timer object doesn't know anything about the time-keeping. It's just a mechanism that allows your timerIdle_Tick() method to be called at regular intervals. So, naturally simply stopping and starting the timer again is going to have no effect at all on the displayed time for the timer.

As with your previous question about this program, you still have not provided a Minimal, Complete, and Verifiable code example. So it's impossible to know for sure what would be needed.

But looking at the code you posted, it seems to me that you can simply assign a new value to your tempo variable, to start the count back at whatever time you want. E.g.:

timerIdle.Stop();
tempo = 300; // 300 seconds, or in other words, 5 minutes
timerIdle.Start();

For what it's worth, your code can be simplified. Well, ignoring for the moment that the "decrement a seconds counter on each tick" is simply the wrong way to implement this (as has been explained to you in your previous question), the body of your Tick handler method could look more like this and still do the same thing:

public static void timerIdle_Tick(object sender, EventArgs e)
{
    tempo--; // decrement first, then segundo and minuto already will be automatically decremented correctly

    // NOTE: it's not clear whether these are even used outside this method.
    // If not, just make them locals and do this computation only in the
    // "else" block below.
    minuto = tempo / 60; // will be 0 if tempo < 60
    segundo = tempo % 60; // will be tempo if tempo < 60

    if (tempo < 0)
    {
        timerIdle.Stop();

        // WARNING: this renders the timerIdle object invalid for future use.
        // If you try to restart the timer without creating a new one after this
        // statement executes, an exception will be thrown. If you intend to ever
        // reuse timerIdle, you should not dispose it here.
        timerIdle.Dispose();

        dgView.addLinha(2, "config_Teste", "TIMER ACABOU", 0);
    }
    else
    {
        // no need to recombine minuto and segundo back into tempo,
        // since tempo was already decremented to start with and
        // continues to have the right value here.

        string temp = string.Format($"{minuto:D2}:{segundo:D2}");
        lblIdle.Text = temp;
        dgView.addLinha(2, "config_Teste", temp, 0);
    }
}

Upvotes: 1

Math-O5
Math-O5

Reputation: 375

Did you try this:

  timerIdle.Enabled = false;
  timerIdle.Enabled = true;

Upvotes: 0

Related Questions