How to allow alphanumeric text in datagridview but exclude negative numbers - vb.net

I'm trying to allow only alphanumeric input in my datagridview column. Is there a way to allow alphanumeric input and also prevent the user from entering negative numbers or leaving the cell blank? If anyone has any suggestions or answers I would greatly appreciate it! :) Here is my code below. I already have the negative and blank cell validation working, but its not allowing me to input non-numeric input.
If (e.ColumnIndex = 0) Then 'checking value for column 1 only
Dim cellData = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
If cellData Is Nothing OrElse IsDBNull(cellData) OrElse cellData.ToString = String.Empty Then ' This will prevent any blank cells
MessageBox.Show("Name Cannot Be Empty")
DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = "Object" ' This is a default value that I want to supply after the message box
ElseIf cellData < 0 Then
MessageBox.Show("Negative Numbers Not Allowed") 'This prevents negative numbers
DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = "Object"
Exit Sub ' Again this a default value I want supplied back to the datagridivewcell
End If
End If
So my code works, except when I enter any type of non-numeric character the program stops and exits.

Try using TryParse like this:
If (e.ColumnIndex = 0) Then 'checking value for column 1 only
Dim cellValue As Integer
If (Int32.TryParse(DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value, cellValue)) Then
If cellValue < 0 Then
MessageBox.Show("Negative Numbers Not Allowed") 'This prevents negative numbers
DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = "Object"
Exit Sub ' Again this a default value I want supplied back to the datagridivewcell
End If
Else
Dim testValue As String = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
If (String.IsNullOrEmpty(testValue)) Then
MessageBox.Show("Name Cannot Be Empty")
DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = "Object" ' This is a default value that I want to supply after the message box
End If
End If
End If

Related

Storing string then displaying it with a label box

I am trying to store the string from an input box and then display it with dashes in the lblbox for a hangman game for a class.
These are the tasks that I am struggling with:
edit the program to allow a Secret Word of any length.
the program will allow the ‘guesser’ to guess 2 times the length of the word. As an example, the word ‘code’ will allow 8 total guesses.
As the user guesses at letters contained in the word the program will:
Count the number of attempts the user has completed.
Replace the appropriate dash (-) with the correct letter, if the correct letter has been guessed.
When all the letters have been guessed correctly all the dashes (-) should be replaced with the appropriate letters, and a message box should appear stating “Great Job playing Hangman.!”
If the user is unable to guess the correct word in the amount of guesses allowed; the dashes (-) should be replaced with GAME OVER! and a message box should appear stating “Sorry the correct word was________”
2 bonus points will be awarded for displaying all incorrect letters guess in a 3rd label control.
4 more additional bonus points will be awarded for not allowing, or counting a user who guesses the same incorrect letter twice.
Here is my code:
Dim strSecretWord As String
Dim strLetterGuessed As String
Dim blnDashReplaced As Boolean
Dim intNumberOfRemainingGuesses As Integer = 10
Dim intNumofGuesses As Integer = 0
lblSecretWord.Text = ""
lblNumberOfAttempts.Text = ""
'start game and have 1st user input a 5 letter word that 2nd player needs to guess
strSecretWord = InputBox("Please input a 5 letter word for user to guess:", "Please input secret word.").ToUpper
'displays five dashes for the secret word
lblSecretWord.Text = lblSecretWord.Text & "-----"
'guessing player recieves inputbox to make letter guesses
MessageBox.Show("The length of the word is 5 letters, you will be given 10 guesses", "10 guesses", MessageBoxButtons.OK)
MessageBox.Show("Player who gets to guess, BE READY!", "Good Luck Guessing", MessageBoxButtons.OK)
'Counts number of attempts player gets (10) and replaces dashes with guessed letter if correct
'If guessed letter was incorrect, user loses a turn
For intNumberofGuesses = 1 To 10
strLetterGuessed = InputBox("Please guess a letter:", "Letter Guess").ToUpper
'Uses an IntIndex counter of 0 to 4 to execute 5 times (5 dashes)
'Also uses the value of intIndex to check each of the 5 locations of the strSecretWord
For intIndex As Integer = 0 To 4
'if the user has guessed a correct letter then remove a dash and insert the correct letter guessed
If strSecretWord.Substring(intIndex, 1) = strLetterGuessed Then
lblSecretWord.Text = lblSecretWord.Text.Remove(intIndex, 1)
lblSecretWord.Text = lblSecretWord.Text.Insert(intIndex, strLetterGuessed)
blnDashReplaced = True
End If
Next intIndex
'If the user guessed a correct letter on their last guess the blnDashReplaced is set and the true condition of the If statement is executed
If blnDashReplaced = True Then
'if there are no more dashes, and the game has been solved.
If lblSecretWord.Text.Contains("-") = False Then
MessageBox.Show("Great Job playign Hangman!", "Game Over", MessageBoxButtons.OK)
lblRemainingNumberOfAttempts.Text = ""
lblNumberOfAttempts.Text = ""
Exit Sub
Else
blnDashReplaced = False
End If
Else
End If
lblNumberOfAttempts.Text = intNumberofGuesses
intNumberOfRemainingGuesses = intNumberOfRemainingGuesses - 1
lblRemainingNumberOfAttempts.Text = intNumberOfRemainingGuesses
Next
lblSecretWord.Text = "GAME OVER!"
MessageBox.Show("Better luck next time. Sorry the correct word was " & strSecretWord & ".", "You Lost", MessageBoxButtons.OK)
lblRemainingNumberOfAttempts.Text = ""
lblNumberOfAttempts.Text = ""
I added a list box to keep the guessed letters. Other comments and explanations in line.
Public Class Form3
'Move this to a class level variable so it can be seen by
'all the methods in the class
Private strSecretWord As String
Private Sub btnStartGame_Click(sender As Object, e As EventArgs) Handles btnStartGame.Click
Dim strLetterGuessed As String
Dim blnDashReplaced As Boolean
Dim intNumberOfRemainingGuesses As Integer
Dim intNumofGuesses As Integer = 0
'Display correct number of dashes
Dim numberOfDashes As Integer = strSecretWord.Length
'Create a string with correct number of dashes
'This uses and overload of the String constructor that takes a Char and an integer
'as arguments and returns a string with that character repeated that number
'of times. The lower case c following "-" indicates that - is a Char.
Dim TotalNumofGuesses = numberOfDashes * 2
lblRemainingNumberOfAttempts.Text = TotalNumofGuesses.ToString
intNumberOfRemainingGuesses = TotalNumofGuesses
Dim dashString As String = New String("-"c, numberOfDashes)
'displays the dashes
lblSecretWord.Text = dashString
'guessing player recieves inputbox to make letter guesses
'You can use an Interpolated string to display variables in line surrounded by { }.
'In older versions of VB String.Format() will yield the same result.
MessageBox.Show($"The length of the word is {numberOfDashes} letters, you will be given {TotalNumofGuesses} guesses", $"{TotalNumofGuesses} guesses", MessageBoxButtons.OK)
MessageBox.Show("Player who gets to guess, BE READY!", "Good Luck Guessing", MessageBoxButtons.OK)
'Counts number of attempts player gets and replaces dashes with guessed letter if correct
'If guessed letter was incorrect, user loses a turn
For counter = 1 To TotalNumofGuesses
strLetterGuessed = InputBox("Please guess a letter:", "Letter Guess").ToUpper
'If lstLettersGuessed.Contains(strLetterGuessed) Then
If lbxLettersGuessed.Items.Contains(strLetterGuessed) Then
MessageBox.Show($"{strLetterGuessed} has already been guessed.", "Try Again")
'need to do this so they are not cheated out of a guess
TotalNumofGuesses += 1
Continue For 'Moves to the next iteration of the For
End If
lbxLettersGuessed.Items.Add(strLetterGuessed)
'lstLettersGuessed.Add(strLetterGuessed)
'Uses an IntIndex counter of 0 to 4 to execute 5 times (5 dashes)
'Also uses the value of intIndex to check each of the 5 locations of the strSecretWord
For intIndex As Integer = 0 To numberOfDashes - 1
'if the user has guessed a correct letter then remove a dash and insert the correct letter guessed
If strSecretWord.Substring(intIndex, 1) = strLetterGuessed Then
lblSecretWord.Text = lblSecretWord.Text.Remove(intIndex, 1)
lblSecretWord.Text = lblSecretWord.Text.Insert(intIndex, strLetterGuessed)
blnDashReplaced = True
End If
Next intIndex
'If the user guessed a correct letter on their last guess the blnDashReplaced is set and the true condition of the If statement is executed
If blnDashReplaced = True Then
'if there are no more dashes, and the game has been solved.
If lblSecretWord.Text.Contains("-") = False Then
MessageBox.Show("Great Job playing Hangman!", "Game Over", MessageBoxButtons.OK)
'Do this at start of game, player wants to see final score
'lblRemainingNumberOfAttempts.Text = ""
'lblNumberOfAttempts.Text = ""
Exit Sub
Else
blnDashReplaced = False
End If
End If
'This is a shorter way of incrementing a variable
intNumofGuesses += 1
'Can't put an integer into a Text property, it needs a string
lblNumberOfAttempts.Text = intNumofGuesses.ToString
'This is a shorter way of decrementing a variable
intNumberOfRemainingGuesses -= 1
'Can't put an integer into a Text property, it needs a string
lblRemainingNumberOfAttempts.Text = intNumberOfRemainingGuesses.ToString
Next
lblSecretWord.Text = "GAME OVER!"
MessageBox.Show("Better luck next time. Sorry the correct word was " & strSecretWord & ".", "You Lost", MessageBoxButtons.OK)
'Do this at start of game
'lblRemainingNumberOfAttempts.Text = ""
'lblNumberOfAttempts.Text = ""
End Sub
Private Sub btnSetUp_Click(sender As Object, e As EventArgs) Handles btnSetUp.Click
lblSecretWord.Text = ""
lblNumberOfAttempts.Text = "0"
lblRemainingNumberOfAttempts.Text = "0"
lbxLettersGuessed.Items.Clear()
'start game and have 1st user input a 5 letter word that 2nd player needs to guess
strSecretWord = InputBox("Please input a word for user to guess:", "Please input secret word.").ToUpper
End Sub
End Class

Visual Basic Input Validation

I am new to Visual Basic programming. I'm using a multi-line textbox to accept only numerical inputs from the users.
I need to remove any white space before adding it to my listbox. For example like ( 8) becomes 8 when added into the listbox and I shouldn't let the user proceed if there is no input or only whitespace as an input. Thank you in advance :)
For i As Integer = 0 To Val(TxtInput.Lines.Count) - 1
If TxtInput.Lines(i) = "" Then 'Ignores newline inputs
'Placeholder Comment
ElseIf IsNumeric(TxtInput.Lines(i)) Then 'Tests for Numbers
Temp.LbInput.Items.Add(TxtInput.Lines(i))
Temp.Show()
Else
MsgBox("Your input must only be in numbers, check for invalid inputs!", 1, "Error")
Temp.LbInput.Items.Clear()
Return
End If
Next
This is the kind of thing linq-to-objects was made for:
Dim result = TxtInput.Lines.
Select(Function(line) line.Trim).
Where(Function(line) Not String.IsNullOrWhitespace(line) AndAlso IsNumeric(line)).
Select(Function(line) Val(line))
You can also do this:
Dim lines = TxtInput.Lines.Select(Function(line) line.Trim)
If lines.Any(Function(line) Not IsNumeric(line)) Then
MsgBox("Your input must only be in numbers, check for invalid inputs!", 1, "Error")
Exit Sub
Else
Dim result = lines.Where(Function(line) Not String.IsNullOrWhitespace(line)).
Select(Function(line) Val(line))
'Do more with "result" here
End If
Just store the trimmed line into a variable
For i As Integer = 0 To TxtInput.Lines.Count - 1
Dim line As String = TxtInput.Lines(i).Trim() '<======================
If line = "" Then 'Ignores newline inputs
'Placeholder Comment
ElseIf IsNumeric(line) Then 'Tests for Numbers
Temp.LbInput.Items.Add(line)
Temp.Show()
Else
MsgBox("Your input must only be in numbers, check for invalid inputs!", 1, "Error")
Temp.LbInput.Items.Clear()
Return
End If
Next
Also, TxtInput.Lines.Count is an Integer already. No need to convert with Val, which, by the way, converts it into a Double.
Note that you can add items of any type to the ListBox, so you could as well convert the line into the desired type. I don't know if you need Integer or Double. Let's assume that you only want integer numbers. then you can change the code to
If TxtInput.Lines.Count = 0 Then
MsgBox("You have not entered anything. Please enter a number!", 1, "Error")
Else
For i As Integer = 0 To TxtInput.Lines.Count - 1
Dim line As String = TxtInput.Lines(i).Trim()
Dim number As Integer
If line = "" Then
MsgBox("Your input is empty. Please enter some numbers!", 1, "Error")
ElseIf Integer.TryParse(line, number) Then 'Tests for Numbers
Temp.LbInput.Items.Add(number)
Temp.Show()
Else
MsgBox("Please enter only valid numbers!", 1, "Error")
Temp.LbInput.Items.Clear()
Return
End If
Next
End If
(Code changed according to your comments.)
If you want doubles, just declare number as Double and convert with Double.TryParse(line, number).

Invalid Cast Expectation Was Unhanded (when checking the contents of a text box)

This code is from a subroutine that checks if a text box entry fits the criteria specified (an integer between 1 and 100).
The first IF statement should check if it is not a numerical entry. If it is not numerical then the contents of the text box should be set blank so that a number can be entered.
The second IF statement should check if the number is larger than 100. If it is then the contents of the text box should be set blank so that an appropriate number can be entered.
The Third IF statement should check if the number is smaller than 1. If it is then the contents of the text box should be set blank so that an appropriate number can be entered.
Finally the contents of the box should be set as the variable.
I initially programmed the first IF statement on its own and it worked. But upon adding the others my program would crash when I typed anything into the text box and the error was as stated in my title. I have looked at multiple solutions and have found nothing for almost 2 days that fixed the problem.
Any suggestions would be appreciated.
Public Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles NumQTextBoxInput.TextChanged
'Check if input is numeric
If Not IsNumeric(NumQTextBoxInput.Text) Then NumQTextBoxInput.Text = ""
If (NumQTextBoxInput.Text > 100) Then
NumQTextBoxInput.Text = ""
End If
If (NumQTextBoxInput.Text < 1) Then
NumQTextBoxInput.Text = ""
End If
ArchwayComputingExamCreator.GlobalVariables.NumOfQuestions = NumQTextBoxInput.Text
'Setting the variable to the contense
End Sub
You should always use the appropriate parse function when accepting text for numbers.
Public Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles NumQTextBoxInput.TextChanged
Dim Value as integer
If Not Integer.TryParse(NumQTextBoxInput.text, Value) OrElse Value < 1 OrElse Value > 100 Then NumQTextBoxInput.Text = ""
... no idea if the archway bit is really what you wanted so left that out ....
End Sub
In this operation:
If Not IsNumeric(NumQTextBoxInput.Text) Then NumQTextBoxInput.Text = ""
Any time the input is not numeric, you set it to a value which is still not numeric. So any numeric comparison will fail:
If (NumQTextBoxInput.Text > 100)
Maybe you meant to set the value to some numeric default?:
If Not IsNumeric(NumQTextBoxInput.Text) Then NumQTextBoxInput.Text = "0"
Or just exit the method entirely when it's not numeric?:
If Not IsNumeric(NumQTextBoxInput.Text) Then
NumQTextBoxInput.Text = ""
Return
End If
Or perhaps something else? However you modify your logic, the point is that you can't perform numeric comparisons on non-numeric strings.

Validating multiple textboxes with multiple checks

I have multiple textboxes in a groupbox, and can successfully cycle through them all. However the checkNumbers sub fails to recognise blank/null entries, and also non-numeric characters. The correctValidation boolean should return true if all the criteria are met (no blanks/nulls, and must be a number between 1-20). Any thoughts on how to solve this would be appreciated.
Private Sub checkNumbers()
Try
For Each txt As TextBox In Me.gbTechnical.Controls.OfType(Of TextBox)()
If txt.Text <> "" And IsNumeric(txt.Text) And (Integer.Parse(txt.Text) >= 1 And Integer.Parse(txt.Text) <= 20) Then
correctValidation = True
Else
correctValidation = False
MsgBox("Please ensure all numbers are between 1 and 20")
Exit Sub
End If
Next
Catch ex As Exception
MessageBox.Show("General: Please ensure all numbers are between 1 and 20")
End Try
End Sub
I would use Integer.TryParse and then >= 1 AndAlso <= 20. You could use this LINQ query:
Dim number As Int32
Dim invalidTextBoxes =
From txt In gbTechnical.Controls.OfType(Of TextBox)()
Where Not Integer.TryParse(txt.Text, number) OrElse number < 1 OrElse number > 20
Dim correctValidation = Not invalidTextBoxes.Any()
Note that you should almost always use AndAlso instead of And and OrElse instead of Or since those operators are Is short-circuiting boolean operators. This can be more efficient and - more important - can prevent errors. Consider this:
Dim text = ""
If txt IsNot Nothing And txt.Text.Length <> 0 Then text = txt.Text
This fails if txt is nothing since the second condition is evaluated even if the first already was evaluated to false which causes a NullReferenceException at txt.Text.
if you only want a number value, why don't you try to use NumericUpDown. You can also set the Minimum and Maximum in property or use
NumericUpDown1.Maximum = 20
so, there won't be a need to do checkNumbers.
Or is there any reason that you have to use textbox??

Input Validation for an integer in DataGridView

I'm able to use the code below to check whether or not a user inputs a string in a datagridview cell. If the user inputs a string a message pops up to tell them "only numeric entries are allowed". This is exactly what I want my code to do. However if I try to use this code in a column of data populated with numbers I get an error message that says "error happened, parsing commit". If anyone is able to figure out what the issue is here I would greatly appreciate it!
If (e.ColumnIndex = 3) Then 'checking numeric value for column 3 only
Dim value As String = DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value
For Each c As Char In value
If Not Char.IsDigit(c) Then
MessageBox.Show("Please Enter numeric Value")
DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = 3 'This will set the defaultvalue of the datagrid cell in question to the value of "3"
Exit Sub
End If
Next
End If
This solution not only checks for non-integer values it also works for every column populated with numbers for the entire datagridview. Also if the user inputs a non-integer if will supply a default value for the datagridviewcell, this default value is the previous number.
Private Sub DataGridView1_DataError(ByVal sender As Object, _
ByVal e As DataGridViewDataErrorEventArgs) _
Handles DataGridView1.DataError
If StrComp(e.Exception.Message, "Input string was not in a correct format.") = 0 Then
MessageBox.Show("Please Enter a numeric Value")
'This will change the number back to original
DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = " "
End If
End Sub
Do this in cellvalidating event ...
If (e.ColumnIndex = 3) Then 'checking numeric value for column 3 only
If Not Isnumeric(e.Formatted.Value) Then
MessageBox.Show("Please Enter numeric Value")
DataGridView1.Rows(e.RowIndex).Cells(e.ColumnIndex).Value = 3 'This will set the defaultvalue of the datagrid cell in question to the value of "3"
Exit Sub
End If
End If