在本系列四個教學課程中,您將製作數學測驗。 測驗包含四個隨機數學問題,測驗者會嘗試在指定的時間內回答。
測驗使用定時器控件。 此控件背後的程式代碼會追蹤經過的時間,並檢查測驗者答案。
在本第三個教學課程中,您將瞭解如何:
- 將定時器控件新增至 Windows Forms 應用程式。
- 為定時器新增事件處理程式。
- 撰寫程式代碼來檢查使用者的答案、顯示訊息,並填入正確的答案。
先決條件
本教學課程是以先前的教學課程為基礎,從 建立數學測驗 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 控件從 工具箱 的 元件 類別移動到您的表單。 控件會出現在設計視窗底部的灰色區域中。
在表單上,選取您剛才新增的定時器圖示,並將其 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語句會使用 NumericUpDown 控件的 Value 屬性來存取控件目前的值。 在下一節中,您會使用相同的 屬性,在每個控件中顯示正確的答案。
將事件處理程式新增至定時器
既然您已經有辦法檢查答案,您可以撰寫 Tick 事件處理程式的程式代碼。 此程式代碼會在定時器引發 Tick 事件之後每秒執行一次。 這個事件處理程式會呼叫 CheckTheAnswer()來檢查測驗者答案。 它也會檢查測驗中經過多少時間。
在窗體上,按兩下 Timer 控件,或選取它,然後選取 [Enter]。 這些動作會新增 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 控件的 Enabled 屬性會設定為
true,讓測驗者可以啟動另一個測驗。
如果
CheckTheAnswer()傳回false,程式代碼會檢查 timeLeft 的值:- 如果這個變數大於 0,定時器會從 timeLeft 減 1。 它也會更新 timeLabel 控件的 Text 屬性,以顯示測驗者剩餘的秒數。
- 如果時間已經用完,定時器會停止並變更timeLabel 文字為時間到了! 消息框宣布測驗結束,並顯示答案。 [開始] 按鈕會再次可供使用。
啟動定時器
若要在測驗開始時啟動定時器,請將三行新增至 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,並將 timeLabel 控件的 Text 屬性設定為 30 秒。 然後定時器控件的 Start() 方法會啟動倒數計時。
執行您的應用程式
儲存程式並加以執行。
選擇 開始測驗。 定時器會開始倒數。 當時間用完時,測驗會結束,答案隨即出現。
開始另一個測驗,並提供數學問題的正確答案。 當您在時間限制內正確回答時,消息框隨即開啟、開始按鈕可供使用,定時器會停止。
下一步
前進到下一個教學課程,以瞭解如何自定義數學測驗。