Muokkaa

Jaa


Tutorial: Add a timer to a math quiz WinForms app

In this series of four tutorials, you'll build a math quiz. The quiz contains four random math problems that a quiz taker tries to answer within a specified time.

The quiz uses a Timer control. The code behind this control tracks the elapsed time and checks the quiz taker's answers.

In this third tutorial, you learn how to:

  • Add a Timer control.
  • Add an event handler for the timer.
  • Write code to check the user's answers, display messages, and fill in the correct answers.

Prerequisites

This tutorial builds on previous tutorials, starting with Create a math quiz WinForms app. If you haven't completed those tutorials, go through them first.

Add a countdown timer

To keep track of time during the quiz, you use a timer component. You also need a variable to store the amount of time that's left.

  1. Add an integer variable that's named timeLeft in the same way that you declared variables in previous tutorials. Put the timeLeft declaration right after the other declarations. Your code should look like the following sample.

    public partial class Form1 : Form
    {
        // Create a Random object called randomizer 
        // to generate random numbers.
        Random randomizer = new Random();
    
        // These integer variables store the numbers 
        // for the addition problem. 
        int addend1;
        int addend2;
    
        // These integer variables store the numbers 
        // for the subtraction problem. 
        int minuend;
        int subtrahend;
    
        // These integer variables store the numbers 
        // for the multiplication problem. 
        int multiplicand;
        int multiplier;
    
        // These integer variables store the numbers 
        // for the division problem. 
        int dividend;
        int divisor;
    
        // This integer variable keeps track of the 
        // remaining time.
        int timeLeft;
    

  1. In Windows Forms Designer, move a Timer control from the Components category of the Toolbox to your form. The control appears in the gray area at the bottom of the design window.

  2. On the form, select the timer1 icon that you just added, and set its Interval property to 1000. Because this interval is in milliseconds, a value of 1000 causes the timer to raise a Tick event every second.

Check the answers

Because the timer raises a Tick event every second, it makes sense to check the elapsed time in a Tick event handler. It's also practical to check the answers in that event handler. If time has run out, or if the answers are correct, the quiz should end.

Before you write that event handler, add a method called CheckTheAnswer() to determine whether the answers to the math problems are correct. This method should be in line with the other methods, such as StartTheQuiz(). Your code should look like the following sample.

/// <summary>
/// Check the answers to see if the user got everything right.
/// </summary>
/// <returns>True if the answer's correct, false otherwise.</returns>
private bool CheckTheAnswer()
{
    if ((addend1 + addend2 == sum.Value)
        && (minuend - subtrahend == difference.Value)
        && (multiplicand * multiplier == product.Value)
        && (dividend / divisor == quotient.Value))
        return true;
    else
        return false;
}

This method determines the answers to the math problems and compares the results to the values in the NumericUpDown controls. In this code:

  • The Visual Basic version uses the Function keyword instead of the usual Sub keyword because this method returns a value.

  • You can't easily enter the multiplication sign (×) and the division sign (÷) by using the keyboard, so C# and Visual Basic accept an asterisk (*) for multiplication and a slash mark (/) for division.

  • In C#, && is the logical and operator. In Visual Basic, the equivalent operator is AndAlso. You use the logical and operator to check whether more than one condition is true. In this case, if the values are all correct, the method returns a value of true. Otherwise, the method returns a value of false.

  • The if statement uses the Value property of a NumericUpDown control to access the control's current value. In the next section, you use the same property to display the correct answer in each control.

Add an event handler to the timer

Now that you have a way to check the answers, you can write the code for the Tick event handler. This code runs every second, after the timer raises a Tick event. This event handler checks the quiz taker's answers by calling CheckTheAnswer(). It also checks how much time has elapsed in the quiz.

  1. On the form, double-click the Timer control, or select it and then select Enter. These actions add a Tick event handler. The code editor appears and displays the Tick handler's method.

    For C#, it adds a line of code in the Form1.Designer.cs code file that hooks up the event handler:

    timer1.Tick += new EventHandler(timer1_Tick);
    

    (For Visual Basic, there's no need for that line, but the event handler contains a handles Timer1.Tick which does the same thing.)

  2. Add the following statements to the new event handler method.

    private void timer1_Tick(object sender, EventArgs e)
    {
        if (CheckTheAnswer())
        {
            // If CheckTheAnswer() returns true, then the user 
            // got the answer right. Stop the timer  
            // and show a MessageBox.
            timer1.Stop();
            MessageBox.Show("You got all the answers right!",
                            "Congratulations!");
            startButton.Enabled = true;
        }
        else if (timeLeft > 0)
        {
            // If CheckTheAnswer() returns false, keep counting
            // down. Decrease the time left by one second and 
            // display the new time left by updating the 
            // Time Left label.
            timeLeft = timeLeft - 1;
            timeLabel.Text = timeLeft + " seconds";
        }
        else
        {
            // If the user ran out of time, stop the timer, show
            // a MessageBox, and fill in the answers.
            timer1.Stop();
            timeLabel.Text = "Time's up!";
            MessageBox.Show("You didn't finish in time.", "Sorry!");
            sum.Value = addend1 + addend2;
            difference.Value = minuend - subtrahend;
            product.Value = multiplicand * multiplier;
            quotient.Value = dividend / divisor;
            startButton.Enabled = true;
        }
    }
    

Each second of the quiz, this method runs. The code first checks the value that CheckTheAnswer() returns.

  • If all answers are correct, that value is true, and the quiz ends:

    • The timer stops.
    • A congratulatory message appears.
    • The Enabled property of the startButton control is set to true so that the quiz taker can start another quiz.
  • If CheckTheAnswer() returns false, the code checks the value of timeLeft:

    • If this variable is greater than 0, the timer subtracts 1 from timeLeft. It also updates the Text property of the timeLabel control to show the quiz taker how many seconds remain.
    • If no time remains, the timer stops and changes the timeLabel text to Time's up! A message box announces that the quiz is over, and the answers are revealed. The start button becomes available again.

Start the timer

To start the timer when the quiz starts, add three lines to the end of the StartTheQuiz() method, as the following sample shows.

/// <summary>
/// Start the quiz by filling in all of the problem 
/// values and starting the timer. 
/// </summary>
public void StartTheQuiz()
{
    // Fill in the addition problem.
    // Generate two random numbers to add.
    // Store the values in the variables 'addend1' and 'addend2'.
    addend1 = randomizer.Next(51);
    addend2 = randomizer.Next(51);

    // Convert the two randomly generated numbers
    // into strings so that they can be displayed
    // in the label controls.
    plusLeftLabel.Text = addend1.ToString();
    plusRightLabel.Text = addend2.ToString();

    // 'sum' is the name of the NumericUpDown control.
    // This step makes sure its value is zero before
    // adding any values to it.
    sum.Value = 0;

    // Fill in the subtraction problem.
    minuend = randomizer.Next(1, 101);
    subtrahend = randomizer.Next(1, minuend);
    minusLeftLabel.Text = minuend.ToString();
    minusRightLabel.Text = subtrahend.ToString();
    difference.Value = 0;

    // Fill in the multiplication problem.
    multiplicand = randomizer.Next(2, 11);
    multiplier = randomizer.Next(2, 11);
    timesLeftLabel.Text = multiplicand.ToString();
    timesRightLabel.Text = multiplier.ToString();
    product.Value = 0;

    // Fill in the division problem.
    divisor = randomizer.Next(2, 11);
    int temporaryQuotient = randomizer.Next(2, 11);
    dividend = divisor * temporaryQuotient;
    dividedLeftLabel.Text = dividend.ToString();
    dividedRightLabel.Text = divisor.ToString();
    quotient.Value = 0;

    // Start the timer.
    timeLeft = 30;
    timeLabel.Text = "30 seconds"; 
    timer1.Start();
}

When your quiz starts, this code sets the timeLeft variable to 30 and the Text property of the timeLabel control to 30 seconds. Then the Start() method of the Timer control starts the countdown.

Run your app

  1. Save your program and run it.

  2. Select Start the quiz. The timer starts to count down. When time runs out, the quiz ends, and the answers appear.

  3. Start another quiz, and provide correct answers to the math problems. When you answer correctly within the time limit, a message box opens, the start button becomes available, and the timer stops.

    Screenshot that shows a completed quiz with 19 seconds remaining. The Start the quiz button is available.

Next steps

Advance to the next tutorial to learn how to customize your math quiz.