vb.netuser-interfacemessageboxlogic-error

Vb.Net Message box with input validation


So i'm getting a new laptop and to help me decide I came up with a points system. I have made an application to help with calculation and it consists of a series to check boxes with different options for different categories of components etc (CPU, RAM etc). They're given points based on how good they are. I have a few lines of code that checks to see if more than one component per category has been selected. If more than 1 has then a message box pops up telling the user then resetting the options. However, the message box comes up twice after the first go.

Error video: https://i.sstatic.net/MDgR4.jpg

This is my first vb.net solo GUI program so be kind.

Many thanks, :)

This is the program UI

Public Class Form1
Dim IS_R54500 As Boolean = False
Dim IS_R53500 As Boolean = False
Dim IS_R34300 As Boolean = False
Dim IS_Gb4 As Boolean = False
Dim IS_Gb8 As Boolean = False
Dim IS_Screen14 As Boolean = False
Dim IS_Screen15 As Boolean = False
Dim IS_SSD128 As Boolean = False
Dim IS_SSD256 As Boolean = False
Dim IS_SSD512 As Boolean = False
Dim IS_USBA As Integer = 0
Dim IS_USBC As Integer = 0
Dim IS_HDMI As Integer = 0
Dim IS_DP As Integer = 0
Dim Total As Integer = 0

Public Sub R54500_CheckedChanged(sender As Object, e As EventArgs) Handles R54500.CheckedChanged
    IS_R54500 = True
End Sub

Public Sub R53500_CheckedChanged(sender As Object, e As EventArgs) Handles R53500.CheckedChanged
    IS_R53500 = True
End Sub

Public Sub R34300_CheckedChanged(sender As Object, e As EventArgs) Handles R34300.CheckedChanged
    IS_R34300 = True
End Sub

Public Sub Gb4_CheckedChanged(sender As Object, e As EventArgs) Handles Gb4.CheckedChanged
    IS_Gb4 = True
End Sub

Public Sub Gb8_CheckedChanged(sender As Object, e As EventArgs) Handles Gb8.CheckedChanged
    IS_Gb8 = True
End Sub

Public Sub Screen14_CheckedChanged(sender As Object, e As EventArgs) Handles Screen14.CheckedChanged
    IS_Screen14 = True
End Sub

Public Sub Screen15_CheckedChanged(sender As Object, e As EventArgs) Handles Screen15.CheckedChanged
    IS_Screen15 = True
End Sub

Public Sub SSD128_CheckedChanged(sender As Object, e As EventArgs) Handles SSD128.CheckedChanged
    IS_SSD128 = True
End Sub

Public Sub SSD256_CheckedChanged(sender As Object, e As EventArgs) Handles SSD256.CheckedChanged
    IS_SSD256 = True
End Sub

Public Sub SSD512_CheckedChanged(sender As Object, e As EventArgs) Handles SSD512.CheckedChanged
    IS_SSD512 = True
End Sub

Public Sub USBA_TextChanged(sender As Object, e As EventArgs) Handles USBA.TextChanged
    IS_USBA = USBA.Text()
End Sub

Public Sub USBC_TextChanged(sender As Object, e As EventArgs) Handles USBC.TextChanged
    IS_USBC = USBC.Text()
End Sub

Public Sub HDMI_TextChanged(sender As Object, e As EventArgs) Handles HDMI.TextChanged
    IS_HDMI = HDMI.Text()
End Sub

Public Sub DP_TextChanged(sender As Object, e As EventArgs) Handles DP.TextChanged
    IS_DP = DP.Text()
End Sub

Public Sub Results_Click(sender As Object, e As EventArgs) Handles Results.Click
    Results.Text = CStr(Total)
End Sub

Public Sub Calculate_Click(sender As Object, e As EventArgs) Handles Calculate.Click
    Total = 0

    If IS_R54500 And IS_R53500 = True Then
        MessageBox.Show("There is more than one option chosen in a certain category." & vbCrLf & "Please fix this error and then try again.", "Error")
        IS_R54500 = False
        IS_R53500 = False
        R54500.CheckState = CheckState.Unchecked
        R53500.CheckState = CheckState.Unchecked
    End If
    If IS_R54500 And IS_R34300 = True Then
        MessageBox.Show("There is more than one option chosen in a certain category." & vbCrLf & "Please fix this error and then try again.", "Error")
        IS_R54500 = False
        IS_R34300 = False
        R54500.CheckState = CheckState.Unchecked
        R34300.CheckState = CheckState.Unchecked
    End If
    If IS_R53500 And IS_R34300 = True Then
        MessageBox.Show("There is more than one option chosen in a certain category." & vbCrLf & "Please fix this error and then try again.", "Error")
        IS_R53500 = False
        IS_R34300 = False
        R53500.CheckState = CheckState.Unchecked
        R34300.CheckState = CheckState.Unchecked
    End If
    If IS_Gb8 And IS_Gb4 = True Then
        MessageBox.Show("There is more than one option chosen in a certain category." & vbCrLf & "Please fix this error and then try again.", "Error")
        IS_Gb4 = False
        IS_Gb8 = False
        Gb4.CheckState = CheckState.Unchecked
        Gb8.CheckState = CheckState.Unchecked
    End If
    If IS_Screen14 And IS_Screen15 = True Then
        MessageBox.Show("There is more than one option chosen in a certain category." & vbCrLf & "Please fix this error and then try again.", "Error")
        IS_Screen14 = False
        IS_Screen15 = False
        Screen14.CheckState = CheckState.Unchecked
        Screen15.CheckState = CheckState.Unchecked
    End If
    If IS_SSD128 And IS_SSD256 = True Then
        MessageBox.Show("There is more than one option chosen in a certain category." & vbCrLf & "Please fix this error and then try again.", "Error")
        IS_SSD128 = False
        IS_SSD256 = False
        SSD128.CheckState = CheckState.Unchecked
        SSD256.CheckState = CheckState.Unchecked
    End If
    If IS_SSD128 And IS_SSD512 = True Then
        MessageBox.Show("There is more than one option chosen in a certain category." & vbCrLf & "Please fix this error and then try again.", "Error")
        IS_SSD128 = False
        IS_SSD512 = False
        SSD128.CheckState = CheckState.Unchecked
        SSD512.CheckState = CheckState.Unchecked
    End If
    If IS_SSD512 And IS_SSD256 = True Then
        MessageBox.Show("There is more than one option chosen in a certain category." & vbCrLf & "Please fix this error and then try again.", "Error")
        IS_SSD512 = False
        IS_SSD256 = False
        SSD512.CheckState = CheckState.Unchecked
        SSD256.CheckState = CheckState.Unchecked
    End If

    If IS_R54500 = True Then
        Total += 3
    End If
    If IS_R53500 = True Then
        Total += 2
    End If
    If IS_R34300 = True Then
        Total += 1
    End If
    If IS_Gb8 = True Then
        Total += 2
    End If
    If IS_Gb4 = True Then
        Total += 1
    End If
    If IS_Screen14 = True Then
        Total += 1
    End If
    If IS_Screen15 = True Then
        Total += 2
    End If
    If IS_SSD128 = True Then
        Total += 1
    End If
    If IS_SSD256 = True Then
        Total += 2
    End If
    If IS_SSD512 = True Then
        Total += 3
    End If
    Total += CInt(IS_USBA)
    Total += CInt(IS_USBC)
    Total += CInt(IS_HDMI)
    Total += CInt(IS_DP)

    ''MessageBox.Show("There is more than one option chosen in a certain category." & vbCrLf & "Please fix this error and then try again.", "Error")

    Results.Text = Total
End Sub

End Class


Solution

  • If you use the proper controls, you can save yourself a lot of code. RadioButtons only allow a single selection in a container. A container can be a group box or a form.

    Using a NumericUpDown will insure you get a number for the Ports area. A user can put anything in a TextBox.

    I used the GetSelectedRadioButton several times in the button code. This function takes a container holding radio buttons and returns the selected radio button. It does this with a bit of Linq magic where it checks each radio button in the container until it finds one where .Checked = True. This radio button is assigned to rb and returned to the calling code. If it doesn't find a checked radio button it returns Nothing.

    If we tried to check the .Name property of the radio button when it is Nothing we would get the dreaded NRE (Null Reference Exception) So, the first thing we do is check if the returned radio button Is Nothing. If the user has failed to make a selection, we show a message box and exit the sub.

    If the user has made a selection we use a Select Case or an If statement to increment Total.

    When it comes to the ports we loop through the controls getting the Value property (a Decimal). To add it to Total, it must first be converted to an Integer.

    Finally display the Total.

    Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
        Dim Total As Integer
        Dim rb = GetSelectedRadioButton(gbProcessor)
        If rb Is Nothing Then
            MessageBox.Show("Please select a Processor.")
            Exit Sub
        Else
            Select Case GetSelectedRadioButton(gbProcessor).Name
                Case "rb545"
                    Total += 3
                Case "rb535"
                    Total += 2
                Case "rb343"
                    Total += 1
            End Select
        End If
        Dim rb1 = GetSelectedRadioButton(gbMemory)
        If rb1 Is Nothing Then
            MessageBox.Show("Please select Memory")
            Exit Sub
        Else
            If rb1.Name = "rb4" Then
                Total += 1
            Else
                Total += 2
            End If
        End If
        Dim rb2 = GetSelectedRadioButton(gbScreenSize)
        If rb2 Is Nothing Then
            MessageBox.Show("Please select a Screen Size.")
            Exit Sub
        Else
            If rb2.Name = "rb14" Then
                Total += 1
            Else
                Total += 2
            End If
        End If
        Dim rb3 = GetSelectedRadioButton(gbStorage)
        If rb3 Is Nothing Then
            MessageBox.Show("Please select Storage size.")
            Exit Sub
        Else
            Select Case rb3.Name
                Case "rb128"
                    Total += 1
                Case "rb256"
                    Total += 2
                Case "rb512"
                    Total += 3
            End Select
        End If
        For Each ctrl As NumericUpDown In gbPorts.Controls.OfType(Of NumericUpDown)
            Total += CInt(ctrl.Value)
        Next
        lblCalculate.Text = Total.ToString
    End Sub
    
    Private Function GetSelectedRadioButton(Container As Control) As RadioButton
        Dim rb = Container.Controls.OfType(Of RadioButton)().FirstOrDefault(Function(r) r.Checked = True)
        Return rb
    End Function