Руководство: Добавление таймера в приложение WinForms для математической викторины
В этой серии четырех учебников вы создадите математический тест. Тест содержит четыре случайных математических задачи, на которые участник теста пытается ответить в течение указанного времени.
Тест использует элемент управления таймера. Код, лежащий в основе этого элемента управления, отслеживает истекшее время и проверяет ответы проверяющего.
В этом третьем руководстве описано, как:
- Добавьте элемент управления таймером.
- Добавьте обработчик событий для таймера.
- Напишите код для проверки ответов пользователя, отображения сообщений и заполнения правильных ответов.
Необходимые условия
Это руководство основано на предыдущих учебниках, начиная с создания приложения WinForms для проведения математических викторин. Если вы еще не прошли эти учебные пособия, сначала пройдите их.
Добавление таймера отсчета
Чтобы отслеживать время во время теста, используйте компонент таймера. Кроме того, требуется переменная, чтобы сохранить время, которое осталось.
Добавьте целочисленную переменную, которая называется timeLeft таким же образом, как и объявленные переменные в предыдущих руководствах. Поместите объявление timeLeft сразу после других объявлений. Код должен выглядеть следующим образом.
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;
В конструкторе Windows Formsпереместите элемент управления Timer из категории компонентов панели элементов в форму. Элемент управления отображается в серой области в нижней части окна конструктора.
В форме выберите значок таймер1, который вы только что добавили, и задайте для свойства Interval значение 1000. Так как этот интервал находится в миллисекундах, значение 1000 приводит к тому, что таймер создает событие Tick каждую секунду.
Проверьте ответы
Так как таймер вызывает событие Tick каждые секунды, имеет смысл проверить истекшее время в обработчике событий Tick. Кроме того, можно проверить ответы в этом обработчике событий. Если время истекло или если ответы верны, тест должен завершиться.
Перед записью этого обработчика событий добавьте метод с именем CheckTheAnswer()
, чтобы определить правильность ответов на математические проблемы. Этот метод должен соответствовать другим методам, таким как StartTheQuiz()
. Код должен выглядеть следующим образом.
/// <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;
}
Этот метод определяет ответы на математические проблемы и сравнивает результаты со значениями в элементах управления NumericUpDown. В этом коде:
Версия Visual Basic использует ключевое слово
Function
вместо обычного ключевого словаSub
, так как этот метод возвращает значение.Вы не можете легко ввести знак умножения (×) и знак деления (÷) с помощью клавиатуры, поэтому C# и Visual Basic принимают звездочку (*) для умножения и косой черты (/) для деления.
В C#
&&
является операторомlogical and
. В Visual Basic это эквивалентный операторAndAlso
. Операторlogical and
используется для проверки правильности нескольких условий. В этом случае, если значения являются правильными, метод возвращает значениеtrue
. В противном случае метод возвращает значениеfalse
.Оператор
if
использует свойство Value элемента управления NumericUpDown для доступа к текущему значению элемента управления. В следующем разделе используется то же свойство для отображения правильного ответа в каждом элементе управления.
Добавление обработчика событий в таймер
Теперь, когда у вас есть способ проверить ответы, можно написать код для обработчика событий Tick. Этот код запускается каждую секунду после того, как таймер вызывает событие Tick. Этот обработчик событий проверяет ответы участника викторины путем вызова CheckTheAnswer()
. Он также проверяет, сколько времени прошло в тесте.
На форме дважды щелкните элемент управления таймером () или выделите его, а затем нажмите ВВОД. Эти действия добавляют обработчик событий Tick. Откроется редактор кода и отображается метод обработчика Tick.
Для C#он добавляет строку кода в файл кода Form1.Designer.cs, который подключает обработчик событий:
timer1.Tick += new EventHandler(timer1_Tick);
(Для Visual Basic нет необходимости в этой строке, но обработчик событий содержит
handles Timer1.Tick
, что делает то же самое.)Добавьте следующие инструкции в новый метод обработчика событий.
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; } }
Каждую секунду викторины запускается этот метод. Код сначала проверяет значение, которое возвращает CheckTheAnswer()
.
Если все ответы верны, значение будет равно
true
, и тест закончится.- Таймер останавливается.
- Появится поздравительное сообщение.
- Для свойства включено элемента управления startButton задано значение
true
, чтобы принять тест может запустить другой тест.
Если
CheckTheAnswer()
возвращаетfalse
, код проверяет значение timeLeft:- Если эта переменная больше 0, таймер вычитает 1 из timeLeft. Также обновляется свойство Text элемента управления timeLabel, чтобы показать участнику викторины, сколько секунд осталось.
- Если время не остается, таймер останавливается и изменяет текст timeLabel на time's up! Поле сообщения сообщает о том, что тест закончен, и ответы отображаются. Кнопка "Пуск" снова становится доступной.
Запуск таймера
Чтобы запустить таймер при запуске теста, добавьте три строки в конец метода StartTheQuiz()
, как показано в следующем примере.
/// <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();
}
При запуске теста этот код задает для переменной timeLeft значение 30, а свойству Textэлемента управления timeLabel значение 30 секунд. Затем метод Start() элемента управления Таймер запускает отсчет.
Запуск приложения
Сохраните программу и запустите ее.
Выберите Запустить тест. Таймер начинает отсчитывать. Когда время истекает, тест заканчивается и отображаются ответы.
Запустите еще один тест и укажите правильные ответы на математические задачи. Когда вы правильно отвечаете в течение срока, откроется окно сообщения, кнопка запуска становится доступной, а таймер останавливается.
Дальнейшие действия
Перейдите к следующему руководству, чтобы узнать, как настроить математический тест.