How can I get the backcolor of a button to change colour if it contains the correct answer? Visual Basic 2010

StackOverflow https://stackoverflow.com/questions/18380477

  •  26-06-2022
  •  | 
  •  

سؤال

I have created a multiple choice quiz, but am struggling with coming up with the correct code to make it so that if the player selects the button containing the correct answer, its BackColor will turn green for a few seconds, before the next question appears automatically and returns to its normal BackColor.

Also, if the player selects the button containing the wrong answer, then its BackColor turns red to establish to the player that they were incorrect.

For this, I have a label called lblQuestion, which contains the question being asked and then four buttons (btnAnswerA, btnAnswerB, btnAnswerC and btnAnswerD) which all contain a potential answer to the question, with of course, only one being correct.

I have been fiddling around with the code for sometime, trying to get it to work, but it doesn't work how I want to, so thought to come on here for some guidance in this matter.

Below is some of the code relating to this issue. I am sure by looking at it, many of you will know where I am going wrong!

Private Sub btnAnswerA_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnswerA.Click

    If strAnswer = "A" Then
        btnAnswerA.BackColor = Color.Green
        intScore = intScore + 100
        lblScore.Text = intScore
    Else
        btnAnswerA.BackColor = Color.Red
        Call GetQuestion(questionNumber)
    End If

    Call GetQuestion(questionNumber)
    prgbarOne.Value = 0

End Sub

Private Sub btnAnswerB_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnswerB.Click

    If strAnswer = "B" Then
        btnAnswerB.BackColor = Color.Green
        intScore = intScore + 100
        lblScore.Text = intScore
    Else
        btnAnswerB.BackColor = Color.Red
        Call GetQuestion(questionNumber)
    End If

    Call GetQuestion(questionNumber)
    prgbarOne.Value = 0

End Sub

Private Sub btnAnswerC_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnswerC.Click

    If strAnswer = "C" Then
        btnAnswerC.BackColor = Color.Green
        intScore = intScore + 100
        lblScore.Text = intScore
    Else
        btnAnswerC.BackColor = Color.Red
        Call GetQuestion(questionNumber)
    End If

    Call GetQuestion(questionNumber)
    prgbarOne.Value = 0

End Sub

Private Sub btnAnswerD_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnswerD.Click

    If strAnswer = "D" Then
        btnAnswerD.BackColor = Color.Green
        intScore = intScore + 100
        lblScore.Text = intScore
    Else
        btnAnswerD.BackColor = Color.Red
        Call GetQuestion(questionNumber)
    End If

    Call GetQuestion(questionNumber)
    prgbarOne.Value = 0

End Sub

Basically, I just need some help with knowing how to get the BackColor to turn green/red (depending on whether they're right or wrong) for a few moments before showing the next question where Call GetQuestion(questionNumber) is and knowing how to get the original BackColor (which is Gray) to return for the next question before the player has clicked on a button.

Hope this makes sense and any help is really appreciated. I apologise, I am still new to programming (as you may tell). Also, if more code is needed, I will submit it.

هل كانت مفيدة؟

المحلول

As APrough has pointed out, you can use the Thread.Sleep Method right before each of your Call GetQuestion(questionNumber).

You can adjust the millisecondsTimeout parameter that represents the number of milliseconds for which the thread is blocked. For example to sleep for 2 seconds:

System.Threading.Thread.CurrentThread.Sleep(2000)

But,

I did try that, but what happens is that it freezes without changing the button colour to green/red whilst the question is shown in the label, so ends up delaying onto the next question where new answers are shown.

The reason of that behavior is explained on MSDN about the Application.DoEvents method, that is also the solution:

If you call DoEvents in your code, your application can handle the other events. For example, if you have a form that adds data to a ListBox and add DoEvents to your code, your form repaints when another window is dragged over it. If you remove DoEvents from your code, your form will not repaint until the click event handler of the button is finished executing.

It's what happen for you, the backcolor is not refreshed because I guess you reset the backcolor in the GetQuestion method. So what you need is to call this method (Application.DoEvents) before the Thread.Sleep method.

Your code would be:

Private Sub btnAnswerA_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnswerA.Click

    If strAnswer = "A" Then
        btnAnswerA.BackColor = Color.Green
        intScore = intScore + 100
        lblScore.Text = intScore
    Else
        btnAnswerA.BackColor = Color.Red
        'Call GetQuestion(questionNumber) no need here, it will be called after
    End If

   'Make sure backcolor is refreshed
    Application.DoEvents()

    'Wait for two second
    System.Threading.Thread.Sleep(2000)

    Call GetQuestion(questionNumber)
    prgbarOne.Value = 0

End Sub

Private Sub btnAnswerB_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnswerB.Click

    If strAnswer = "B" Then
        btnAnswerB.BackColor = Color.Green
        intScore = intScore + 100
        lblScore.Text = intScore
    Else
        btnAnswerB.BackColor = Color.Red
        'Call GetQuestion(questionNumber) no need here, it will be called after
    End If

    'Make sure backcolor is refreshed
    Application.DoEvents()

    'Wait for two second
    System.Threading.Thread.Sleep(2000)

    Call GetQuestion(questionNumber)
    prgbarOne.Value = 0

End Sub

Private Sub btnAnswerC_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnswerC.Click

    If strAnswer = "C" Then
        btnAnswerC.BackColor = Color.Green
        intScore = intScore + 100
        lblScore.Text = intScore
    Else
        btnAnswerC.BackColor = Color.Red
        'Call GetQuestion(questionNumber) no need here, it will be called after
    End If

    'Make sure backcolor is refreshed
    Application.DoEvents()

    'Wait for two second
    System.Threading.Thread.Sleep(2000)

    Call GetQuestion(questionNumber)
    prgbarOne.Value = 0

End Sub

Private Sub btnAnswerD_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAnswerD.Click

    If strAnswer = "D" Then
        btnAnswerD.BackColor = Color.Green
        intScore = intScore + 100
        lblScore.Text = intScore
    Else
        btnAnswerD.BackColor = Color.Red
        'Call GetQuestion(questionNumber) no need here, it will be called after
    End If

    'Make sure backcolor is refreshed
    Application.DoEvents()

    'Wait for two second
    System.Threading.Thread.Sleep(2000)

    Call GetQuestion(questionNumber)
    prgbarOne.Value = 0

End Sub

نصائح أخرى

Put in

System.Threading.Thread.CurrentThread.Sleep(1000)

right before each of your Call GetQuestion(questionNumber). The 1000 above is milliseconds, so adjust as you need.

Do a Google search for vb.net timer control. Start a timer after they click the button and handle it's .Tick() event to reset the BG colors of the buttons as well as start the next question. This way it will ensure that the application does not become unresponsive and will properly transition.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top