VB.net timer tick event question - vb.net

I wrote the following code to build a basic game that makes two cars race (randomgenerator) and let the user pick their bets on the end results. I've gone terribly wrong somewhere in that my cars only race halfway then get stuck behind the start line and the programme keeps repeating the beeping and the messsagebox.show and adding results to the 'incorrect' box. I've spent the last three days trying to figure out where I've gone wrong and I'm just missing it. Thank you for taking the time to look at this. I really appreciate any advice.
The only way to terminate the application is to hit 'stop debugging'.
Option Explicit On
Option Strict On
Public Class MainForm
Private Sub exitButton_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles exitButton.Click
Me.Close()
End Sub
Private Sub MainForm_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
'fills the list box with items, then selects the first item
resultListBox.Items.Add("No guess")
resultListBox.Items.Add("Tie")
resultListBox.Items.Add("Red Car wins")
resultListBox.Items.Add("White car wins")
resultListBox.SelectedIndex = 0
End Sub
Private Sub startButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles startButton.Click
raceTimer.Enabled = True
End Sub
Private Sub raceTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles raceTimer.Tick
' moves two cars from a starting line to a finish line on the form
' displays a message indicating the race results
' calculates and displays the number of times the user selects the
' correct race result from the resultlistbox, and the number
' of times the user selects an incorrect race result
Dim randomgenerator As New Random
Dim whitenewlocation As Integer
Dim rednewlocation As Integer
Dim raceresult As String
Dim userchoice As String
Dim finishline As Integer = finishTextBox.Left + 1
Static numbercorrect As Integer
Static numberincorrect As Integer
' save the user's list box selection, then disable the list box
userchoice = resultListBox.SelectedItem.ToString
resultListBox.Enabled = False
'calculate the new location of each picture box's right border
' don't allow the right border to go beyond the finish line
whitenewlocation = whitePictureBox.Right + randomgenerator.Next(0, 11)
If whitenewlocation > finishline Then
whitenewlocation = finishline
End If
rednewlocation = redPictureBox.Right + randomgenerator.Next(0, 11)
If rednewlocation > finishline Then
rednewlocation = finishline
End If
'move each picture box toward the finish line
whitePictureBox.SetBounds(whitenewlocation - whitePictureBox.Width, 0, 0, 0, BoundsSpecified.X)
redPictureBox.SetBounds(rednewlocation - redPictureBox.Width, 0, 0, 0, BoundsSpecified.X)
'the following selection structure is processed only when at least
' one of the picture boxes is at the finish line
If whitePictureBox.Right = finishline _
OrElse redPictureBox.Right = finishline Then
'disable the timer
raceTimer.Enabled = False
End If
'sound a beep to indicate the end of the race
For x As Integer = 1 To 5
Console.Beep(100, 100)
Next x
'store the result of the race in a variable
If whitenewlocation = rednewlocation Then
raceresult = "Tie"
ElseIf whitenewlocation > rednewlocation Then
raceresult = "White car wins"
Else
raceresult = "red car wins"
End If
'display the race results
MessageBox.Show("Race Over!" & ControlChars.NewLine & raceresult, _
"Car Race", MessageBoxButtons.OK, MessageBoxIcon.Information)
'move the picture boxes back to the starting line
whitePictureBox.SetBounds(12, 0, 0, 0, BoundsSpecified.X)
redPictureBox.SetBounds(12, 0, 0, 0, BoundsSpecified.X)
'if the user did not want to guess the race results, then
'don't update or display the counter values; otherwise,
'compare the race results to the user's selection and update
' the appropriate counter, then display both counter values
If userchoice <> "no guess" Then
If raceresult = userchoice Then
numbercorrect = numbercorrect + 1
Else
numberincorrect = numberincorrect + 1
End If
correctLabel.Text = Convert.ToString(numbercorrect)
incorrectLabel.Text = Convert.ToString(numberincorrect)
End If
'enable the list box
resultListBox.Enabled = True
End Sub
End Class

Your timer is doing everything at every tick. The code that handle the end of the race is processed every tick of the timer. It should be enclosed in the if-logic that handles the end of the race.
Allmost eveything after the comment "sound a beep to indicate the end of the race" should be inside the check for end of race:
If whitePictureBox.Right = finishline OrElse redPictureBox.Right = finishline Then
'put all logic of the "ending" of the race here
end if
So this code will work as you expected:
Private Sub raceTimer_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RaceTimer.Tick
' moves two cars from a starting line to a finish line on the form
' displays a message indicating the race results
' calculates and displays the number of times the user selects the
' correct race result from the resultlistbox, and the number
' of times the user selects an incorrect race result
Dim randomgenerator As New Random
Dim whitenewlocation As Integer
Dim rednewlocation As Integer
Dim raceresult As String
Dim userchoice As String
Dim finishline As Integer = finishTextBox.Left + 1
Static numbercorrect As Integer
Static numberincorrect As Integer
' save the user's list box selection, then disable the list box
userchoice = resultListBox.SelectedItem.ToString
resultListBox.Enabled = False
'calculate the new location of each picture box's right border
' don't allow the right border to go beyond the finish line
whitenewlocation = whitePictureBox.Right + randomgenerator.Next(0, 11)
If whitenewlocation > finishline Then
whitenewlocation = finishline
End If
rednewlocation = redPictureBox.Right + randomgenerator.Next(0, 11)
If rednewlocation > finishline Then
rednewlocation = finishline
End If
'move each picture box toward the finish line
whitePictureBox.SetBounds(whitenewlocation - whitePictureBox.Width, 0, 0, 0, BoundsSpecified.X)
redPictureBox.SetBounds(rednewlocation - redPictureBox.Width, 0, 0, 0, BoundsSpecified.X)
'the following selection structure is processed only when at least
' one of the picture boxes is at the finish line
If whitePictureBox.Right = finishline _
OrElse redPictureBox.Right = finishline Then
'disable the timer
RaceTimer.Enabled = False
'sound a beep to indicate the end of the race
For x As Integer = 1 To 5
Console.Beep(100, 100)
Next x
'store the result of the race in a variable
If whitenewlocation = rednewlocation Then
raceresult = "Tie"
ElseIf whitenewlocation > rednewlocation Then
raceresult = "White car wins"
Else
raceresult = "red car wins"
End If
'display the race results
MessageBox.Show("Race Over!" & ControlChars.NewLine & raceresult, _
"Car Race", MessageBoxButtons.OK, MessageBoxIcon.Information)
'move the picture boxes back to the starting line
whitepicturebox.SetBounds(12, 0, 0, 0, BoundsSpecified.X)
redpicturebox.SetBounds(12, 0, 0, 0, BoundsSpecified.X)
'if the user did not want to guess the race results, then
'don't update or display the counter values; otherwise,
'compare the race results to the user's selection and update
' the appropriate counter, then display both counter values
If userchoice <> "no guess" Then
If raceresult = userchoice Then
numbercorrect = numbercorrect + 1
Else
numberincorrect = numberincorrect + 1
End If
correctlabel.Text = Convert.ToString(numbercorrect)
incorrectlabel.Text = Convert.ToString(numberincorrect)
End If
'enable the list box
Resultlistbox.Enabled = True
End If
End Sub

Related

Progress bar gets stuck at 100%

I've programmed a "Please wait" form in which I inserted a progress bar. I looked around how to program a progress bar and this is what I did. First of all I programmed the button - Button3_Click - I press to start. Then I programmed the timer - Timer1_Tick -and so I wrote:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Timer1.Enabled = True
Timer1.Interval = 50
Timer1.Start()
*[calculus code]*
If Form18.ProgressBar1.Value = 100 Then
Form18.Hide()
hrrspkexcel.Visible = True
End If
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
iProgressBarValue += 1
Select Case iProgressBarValue
Case 1, 3, 5, 7, 9
Form18.ProgressBar1.ForeColor = Color.White
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Case 2, 4, 6, 8
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Case 10
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Timer1.Stop()
Timer1.Enabled = False
End Select
End Sub
I can't understand why the progress bar gets stuck at 100% and neither form18 gets hidden, nor hrrspkexcel becomes visible. Where am I doing wrong? Thanks for any support. Best regards.
Edit: I tried to edit my code as comments say:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Timer1.Enabled = True
Timer1.Interval = 50
Timer1.Start()
[calculus code]
iProgressBarValue += 1
Select Case iProgressBarValue
Case 1, 3, 5, 7, 9
Form18.ProgressBar1.ForeColor = Color.White
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Case 2, 4, 6, 8
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Case 10
Form18.ProgressBar1.Value = (iProgressBarValue * 10)
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Timer1.Stop()
Timer1.Enabled = False
End Select
If Form18.ProgressBar1.Value = 100 Then
Form18.Hide()
hrrspkexcel.Visible = True
End If
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
If Form18.ProgressBar1.Value = 100 Then
Timer1.Stop()
Timer1.Enabled = False
End If
End Sub
In this case, progress bar gets stuck at 10%.
Edit II: Following suggestions in comment, I removed the timer and based my progress bar on the entity of the calculus code (Form18.ProgressBar1.Maximum). Anyway, what is reported under [calculus code] is an heavy Excel export so the progress bar freezes to 0% until exportation has ended and then start running (I set loading cursor to understand when exportation has ended), so maybe I'd need of a BackgroundWorker to make my bar progressing while exporting? (I'm a beginner programmer and I read somewhere something about this, but I don't know if this solution is suitable for me, so I'm asking).
At last, this is how I corrected my code:
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Form18.ProgressBar1.Minimum = 0
Form18.ProgressBar1.Value = 0
Form18.ProgressBar1.Maximum = [if loop criteria based on my code]
Form18.ProgressBar1.Increment(1)
Form18.Show()
[calculus code - excel export]
If Form18.ProgressBar1.Value = Form18.ProgressBar1.Maximum Then
Form18.Hide()
hrrspkexcel.Visible = True
End If
End Sub
With this edit, my ProgressBar freezes at 0% even if exportation has already ended, so I'm obviously doing wrong somewhere. Thanks for all the support you're giving to me.
Edit III: I managed in making progressbar working using a for loop to increment its value, as you suggested me, with a proportional equation to percentage and to overcome the problem about the maximum value of the bar, that's always set on 100. So thanks all of you for your support. The last thing I want to ask you - if I'm not offtopic - is how to make my loading form - with the progressbar - on foreground and to "lock" interaction with all other forms.
Edit III BIS: I've tried to use Backgroundworker in order to overcome the loading-form freezing. This is the first time I'm using this command and I don't know if it's the right way to make it comunicating to a ShowDialog Form. This is what I wrote:
Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
Form18.ProgressBar1.Minimum = 0
Form18.ProgressBar1.Value = 0
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Form18.ShowDialog()
[excel calculus export]
If Form18.ProgressBar1.Value = Form18.ProgressBar1.Maximum Then
Form18.Hide()
hrrnativexcel.Visible = True
End If
End Sub
I'm always getting the same trouble: when Form18 appears, remains on 0% loading.
Edit IV: I'm having an issue about progressbar increment for the following situation: I have two for loops for exporting values in excel and the upper bound of this loops are different. So I've created a third for loop, whose upper bound is the sum of the upper bounds of the two abovementioned for loops, in order to increment the progressbar progress. When it reaches 100%, it starts again going in loop. How could I solve this issue? Here is the code I'm using:
For i = 1 To CInt(Form6.ListBox1.Items.Count)
For j = 1 To CInt(Form10.ListBox1.Items.Count)
For k = 0 To CInt(CInt(Form6.ListBox1.Items.Count) + CInt(Form10.ListBox1.Items.Count))
hrrspkexcel.Cells(j + 1, 1).value = Form10.ListBox2.Items(CInt(j + 1) - 2)
hrrspkexcel.Cells(i + 1, 2).value = Form6.ListBox1.Items(CInt(i + 1) - 2)
Form18.ProgressBar1.Value = CInt(100 * k / (CInt(Form6.Label9.Text) + CInt(Form10.ListBox1.Items.Count)))
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Next
Next
Next
Thanks in advance.
Edit V: I've updated my code following comments in order to solve the issue described in Edit IV. This is what I wrote:
Dim pbloop As Integer
pbloop = CInt(Form10.ListBox1.Items.Count) * CInt(Form6.ListBox1.Items.Count)
For p = 1 To pbloop
For i = 1 To CInt(Form6.ListBox1.Items.Count)
For j = 1 To CInt(Form10.ListBox1.Items.Count)
hrrspkexcel.Cells(i + 1, 4).value = Form6.ListBox1.Items(CInt(i + 1) - 2)
hrrspkexcel.Cells(i + 1, 3).value = Form6.ListBox2.Items(CInt(i + 1) - 2)
hrrspkexcel.Cells(j + 1, 1).value = Form10.ListBox1.Items(CInt(j + 1) - 2)
hrrspkexcel.Cells(j + 1, 2).value = Form10.ListBox2.Items(CInt(j + 1) - 2)
Form18.ProgressBar1.Value = CInt(100 * p / pbloop)
Form18.Label3.Text = Form18.ProgressBar1.Value & (" %")
Next
Next
I'm getting stuck always at 0% and progress bar that doesn't increase.
This is not the true answer of the problem but a sample to show you how to use a progress bar.
This code is not beautiful, I know, it's for the example. Please be careful when you use a textbox text as a number without check what is written.
Imports System.Threading
Public Class Form1
Private Sub btnGo_Click(sender As Object, e As EventArgs) Handles btnGo.Click
' Initialisation of the progressbar
myProgressbar.Value = 0
myProgressbar.Maximum = tbxTo.Text
lbxInfos.Items.Clear() ' Clear the content in the listbox1 if it's not the first run
' This simulate your [calculus code], I just add an information in the listbox
For i As Integer = tbxFrom.Text To tbxTo.Text
myProgressbar.Value = i ' Set the progressbar avancement
lbxInfos.Items.Add("This is the loop n° " & i & " !")
lbxInfos.Refresh() ' Just because the listbox will not be refresh until the end of the sub
Thread.Sleep(200) ' The code is too fast, I add this to see the progress (= wait 200 ms)
Next
MsgBox("This is the end ! Now the form will be closed")
Me.Close()
End Sub
End Class
Try something more like this out:
Private Async Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
Button3.Enabled = False
hrrspkexcel.Visible = False ' changed this to a Label next to the button just for demonstration
Dim f18 As New Form18
f18.ProgressBar1.Minimum = 0
f18.ProgressBar1.Value = 0
f18.ProgressBar1.Maximum = 100 ' <-- leave the maximum at 100!
f18.Show(Me)
Dim pct As Integer
Dim maximum As Integer = 319 ' <-- figure out the max value based on your "calculus code"
Await Task.Run(Sub()
' [calculus code - excel export]
For i As Integer = 0 To maximum
System.Threading.Thread.Sleep(50) ' <- some kind of processing going on
' calculate the percentage based on your loop value "i" and the "maximum":
pct = CDbl(i) / CDbl(maximum) * 100 ' <-- scale your loop value to 100
Try
f18.ProgressBar1.Invoke(Sub()
f18.ProgressBar1.Value = pct
End Sub)
Catch ex As Exception
' User closed the progressform, create another one
Me.Invoke(Sub()
f18 = New Form18
f18.ProgressBar1.Minimum = 0
f18.ProgressBar1.Value = 0
f18.ProgressBar1.Maximum = 100 ' <-- leave it at 100
f18.Show(Me)
' make progressbar immediately jump to the right spot
f18.ProgressBar1.Value = f18.ProgressBar1.Maximum
f18.ProgressBar1.Value = pct
End Sub)
End Try
Next
End Sub)
' when we hit here, the "calculus code" above completed
f18.Close()
hrrspkexcel.Visible = True ' changed this to a Label next to the button just for demonstration
Button3.Enabled = True
End Sub
Here's what it looks like in action:
You current code reads as if you want the Progress Bar to update on a button click a maximum of 10 times before hiding the form. Is that your intention? I would have expected that you want the "Please wait ..." form to stay visible with the progress bar updating every, say, second, then disappear?
Using a timer for the latter is fine but for the former, you can simply update the progress bar directly - as you are doing - without a timer.
Also, you don't need to multiply your progress bar value by 10; you can simply set the progress bar Maximum value to 10.
Also, since you change the ForeColor value on the first click, you can probably dispense with the Case Select {even|odd} test because the code is otherwise identical.
So without the timer or the color change and with Progress Bar Maximum = 10, all you need to do is:
Form18.ProgressBar1.Value = iProgressBarValue
Form18.Label3.Text = $"{iProgressBarValue} %")
No need for the Case Select.
Another option for the PB is to use the PerformStep() method to increment it. Just set the Step property to 1 for this approach.

Using vb.net Count all occurrences of vbCrLf in TextBox

I have a TextBox that I am trying to count all the occurrences of vbCrLf.
The counting is working, the issue is every time a vbCrLf is issued I would like to subtract 33 from some Integer.
The code as written now only subtracts the number of vbCrLf, NOT the number + 33.
Question is how to subtract 33 every time the Enter Key is pressed and a vbCrLf is issued ?
I have posted Updated Code The Question Was Answered and Issues SOLVED
I have also added additional code that enhances the management of the TextBox
You will need these Imports
Imports System.IO
Imports System.Text
Public Class frmThree
Dim path As String = "C:/Users/Me/source/repos/TestForms/TestForms/Resource/"
Dim total As Integer
Dim vbLfTotal As Integer
Dim chrPermited As Integer = 333 'chrPermited
Private Sub btnBack_Click(sender As Object, e As EventArgs) Handles btnBack.Click
Me.Close()
frmOne.Show()
End Sub
Private Sub tbHaveOne_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbHaveOne.TextChanged
Dim spaceCount, letterCount, carReturn As Integer
spaceCount = 0
letterCount = 0
carReturn = 0
Dim str As String = tbHaveOne.Text
For Each chr As Char In str
If chr = vbLf Then
carReturn += 1
ElseIf Char.IsLetterOrDigit(chr) Then
letterCount += 1
ElseIf Char.IsWhiteSpace(chr) Then
spaceCount += 1
End If
Next
vbLfTotal = carReturn * 29
total = chrPermited - letterCount - spaceCount - vbLfTotal
tbHaveTwo.ForeColor = Color.Black
tbHaveTwo.Text = total & " More Character Can Be Entered"
While total < 10
tbHaveTwo.Clear()
tbHaveTwo.ForeColor = Color.Red
tbHaveTwo.Text = "Only " & total & " More Character Can Be Entered"
Exit While
End While
If total = 5 Then
PlaySystemSound()
End If
If total < 1 Then
tbHaveTwo.Clear()
tbHaveTwo.Text = "No More Data Entry" & total
Call ansQ()
End If
End Sub
Sub PlaySystemSound()
My.Computer.Audio.PlaySystemSound(
System.Media.SystemSounds.Hand)
End Sub
Public Sub ansQ()
Const Msg As String = "YES Save Data" + vbCrLf + vbNewLine + "NO CANCEL"
Const Title As String = "Save or Exit"
Const Style = vbYesNo + vbQuestion + vbDefaultButton2
Dim result = MsgBox(Msg, Style, Title)
If result = vbYes Then
Call writeDATA()
ElseIf result = vbNo Then
'tbHaveOne.ReadOnly = True
'tbHaveOne.Enabled = False
tbHaveTwo.Text = "NO Was Selected"
'result = 0
End If
End Sub
Public Shared Sub tbHaveOne_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles tbHaveOne.KeyDown
'NOTE this Sub is Shared It seems to run all the time like a listener
If e.KeyCode = Keys.Enter And frmThree.total < 40 Then
e.SuppressKeyPress = True
End If
End Sub
The TextBox.Lines.Count returns the count of the lines separated by newline characters (ControlChars.NewLine or Environment.NewLine when you hit the Enter key.) and not the count of the word-wrapped lines in a multiline TextBox. If you set the WordWrap property to False you will see the difference. See the TextBoxBase.Lines remarks section.
You could call the SendMessage method and the EM_GETLINECOUNT message if you need to get the count of the lines regardless whether they are word-wrapped or separated new lines:
Imports System.Runtime.InteropServices
Private Const EM_GETLINECOUNT As UInteger = &HBA
<DllImport("user32.dll")>
Private Shared Function SendMessage(ByVal hWnd As IntPtr,
ByVal msg As Integer,
ByVal wp As IntPtr,
ByVal lp As IntPtr) As IntPtr
End Function
Private Sub PrintCounts()
Dim c = tbHaveOne.Text.
Aggregate(New With {
.WhiteSpaces = 0, .Lf = 0, .NewLines = 0, .Lines = 0, .Others = 0
},
Function(x, y)
x.Lf += If(y = ControlChars.Cr, 1, 0)
x.WhiteSpaces += If(Char.IsSeparator(y), 1, 0)
x.Others += If(Not Char.IsWhiteSpace(y), 1, 0)
Return x
End Function)
c.NewLines = tbHaveOne.Lines.Count
c.Lines = SendMessage(tbHaveOne.Handle, EM_GETLINECOUNT,
IntPtr.Zero, IntPtr.Zero).ToInt32
tbHaveTwo.Text = $"WhiteSpaces: {c.WhiteSpaces} Lf: {c.Lf} " +
$"New Lines: {c.NewLines} Lines {c.Lines} Others: {c.Others}"
End Sub
Private Sub tbHaveOne_TextChanged(sender As Object,
e As EventArgs) Handles tbHaveOne.TextChanged
PrintCounts()
End Sub
Please note:
The Char.IsSeparator method is used to get the count of the white spaces since the Char.IsWhiteSpace method will return True when evaluating; vbCr, vbLf, vbCrLf, vbTab, ...etc. Alternatively, you can combine the Char.IsWhiteSpace and the Char.IsControl methods to evaluate the white spaces. The Remarks section has more.
The Others is the count of everything else including the letters, digits, punctuations, symbols...etc. You may wont to examine the other Char.IsXXX methods of the Char structure.
Check out the values of the Lines and NewLines fields as you type.
You can't check if the current character is vbcrlf because CRLF is two characters. Just check for the LF, this way if you ever use the logic on a file prepared by a unix system, it still works (unix has LF, Windows has CRLF)
Private Sub tbHaveOne_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tbHaveOne.TextChanged
Dim spaceCount = 0
Dim letterCount = 0
Dim lineCount = 0
For Each c As Char In tbHaveOne.Text
If c = vbLf Then
lineCount += 1
ElseIf Char.IsLetterOrDigit(c) Then
letterCount += 1
ElseIf Char.IsWhiteSpace(c) Then
spaceCount += 1
End If
Next c
someInteger -= (lineCount * 33)
The System.Char has static methods that check characters are in certain Unicode ranges - for your letter count you were counting anything that wasn't a space, including carriage returns, punctuation and other things that aren't letters, as letters. You're free to carry on doing that if you want but it'll maybe lead to a bit of a confusing count if you triple count the newlines
The counting is working the issue is every time a vbCrLf is issued I would like to subtract 33 from some Integer
The code as written now only subtracts the number of vbCrLf NOT the number + 33
I didn't quite get this. You say you want to subtract 33 every time there is a new line, which is what I've done. The second sentence reads like the requirement is to subtract the (number of new lines + 33) from someInteger. If this is what you want to do, change the * on the last line to +
Question is how to subtract 33 every time the Enter Key is pressed and a vbCrLf is issued ?
This is a different thing entirely to "count all occurrences of"; it isn't to do with counting the lines in a textbox, and you can't do it from such code. Counting the number of times the user has ever pressed enter in a textbox needs a hook to the event raised when a user pressed a key while the box had focus. Add a handler for the KeyPress or KeyDown event:
Private Sub tbHaveOne_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles tbHaveOne.KeyPress 'KeyEventArgs for KeyDown event
If e.KeyChar = vbCr Then 'use e.KeyCode = Keys.Enter in KeyDown event
someInteger -= 33
End If
End Sub
We have a lot of great Discussion and Fixed Answers on this question
One of the questions in the discussion was how to handle punctuation and special characters
We would like to offer this code as a way to manage both punctuation and special characters
Dim spaceCount, letterCount, carReturn, punCount, syCount As Integer
spaceCount = 0
letterCount = 0
carReturn = 0
punCount = 0
syCount = 0
Dim str As String = tbHaveOne.Text
For Each chr As Char In str
If chr = vbLf Then
carReturn += 1
ElseIf Char.IsLetterOrDigit(chr) Then
letterCount += 1
ElseIf Char.IsWhiteSpace(chr) Then
spaceCount += 1
ElseIf Char.IsPunctuation(chr) Then
punCount += 1
ElseIf Char.IsSymbol(chr) Then
syCount += 1
End If
Next
vbLfTotal = carReturn * 29
total = chrPermited - letterCount - spaceCount - vbLfTotal - punCount - syCount
tbHaveTwo.ForeColor = Color.Black
tbHaveTwo.Text = total & " More Character Can Be Entered"

Food Survey Application

Okay so this code is a list of items in a combobox and you have to pick one item and then choose a radiobutton like or dislike and then hit vote.The results list box should total up all the votes every time you click like or dislike and hit vote. When I click like and press vote nothing shows up in the results box but when I hit dislike and press vote it shows up and the total is correct for the like I pressed and hit vote so it shows 1 for each. It stays that way the whole time while the program is running, so if I hit like 3 more times it won't update in list box until I hit dislike and press vote. How do I code to show up and update on both like and dislike votes?
Here is my code:
Public Class FoodSurveyForm
Dim votes As Integer(,) = New Integer(0 To 3, 0 To 1) {}
' handles Food Survey Form's Load event
Private Sub FoodSurveyForm_Load(sender As System.Object,
e As System.EventArgs) Handles MyBase.Load
foodsComboBox.SelectedIndex = 0 ' select first food in list
End Sub ' FoodSurveyForm_Load
Private Sub voteButton_Click(sender As System.Object, e As System.EventArgs) Handles voteButton.Click
Dim index As Integer = foodsComboBox.SelectedIndex
'if statement to add like and dislike votes
If likeRadioButton.Checked Then
votes(index, 0) += 1
ElseIf dislikeRadioButton.Checked Then
votes(index, 1) += 1
DisplayVotes()
End If
End Sub
Sub DisplayVotes() 'call DisplayVotes sub procedure
resultsListBox.Items.Clear()
'header for resultListBox
resultsListBox.Items.Add("Menu Item" & ControlChars.Tab & "Like" _
& ControlChars.Tab & "Dislike")
For count As Integer = 0 To foodsComboBox.Items.Count - 1
resultsListBox.Items.Add(foodsComboBox.Items(count).ToString & ControlChars.Tab & votes(count, 0) & _
ControlChars.Tab & votes(count, 1))
Next count
End Sub ' Display Votes
End Class ' FoodSurveyForm
DisplayVotes() must go outside of the if block:
Private Sub voteButton_Click(sender As System.Object, e As System.EventArgs) Handles voteButton.Click
Dim index As Integer = foodsComboBox.SelectedIndex
'if statement to add like and dislike votes
If likeRadioButton.Checked Then
votes(index, 0) += 1
ElseIf dislikeRadioButton.Checked Then
votes(index, 1) += 1
End If
DisplayVotes()
End Sub

Add value to DataGridviewComboBoxColumn without losing focus

I have a DataGridView in my form that has a ComboBoxColumn that holds a hard-coded list of plants. I also give the user the option to add other plants if "Other" is selected.
When the user selects "Other", he puts the new grass name in the message box.
However, after OK is clicked, the new name isn't added to the combobox. (The value for Plant Spacing is added programmatically)
Only by clicking on another cell in the table is the new name added.
How can I get the combobox to update without needing to losing focus?
Here is the code I'm using when the Combobox is clicked
Private Sub DataGridView1_EditingControlShowing(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewEditingControlShowingEventArgs) Handles DataGridView1.EditingControlShowing
CB = TryCast(e.Control, System.Windows.Forms.ComboBox)
If CB IsNot Nothing Then
RemoveHandler CB.SelectedIndexChanged, AddressOf DGVComboIndexChanged
AddHandler CB.SelectedIndexChanged, AddressOf DGVComboIndexChanged
End If
' Other event handlers removed and added here
End Sub
Private Sub DGVComboIndexChanged(ByVal sender As Object, ByVal e As EventArgs)
' Do what you like with the current ComboBoxCell.
'System.Windows.Forms.MessageBox.Show(String.Format( _
'"The SelectedIndex was changed in ComboBoxCell: {0}" & _
'Environment.NewLine & _
'"The current item is: {1}", _
'Me.DataGridView1.CurrentCellAddress.ToString(), _
'CB.SelectedItem.ToString()))
Dim TryAgain As Boolean = True
Dim Letters As String = "abcdefghijklmnopqrstuvwxyz1234567890"
Dim ComboColumn As System.Windows.Forms.DataGridViewComboBoxColumn
ComboColumn = DataGridView1.Columns(0)
Try
If CB.SelectedItem.ToString = "Other" Then
While TryAgain
OtherGrass = Microsoft.VisualBasic.InputBox("Enter the alternate plant name", "Other plant", "")
If OtherGrass = "" Then
'return the cell to ""
DataGridView1.CurrentRow.Cells(0).Value = ""
Exit Sub
End If
For i As Integer = 1 To Len(Letters)
If InStr(LCase(OtherGrass), Mid(Letters, i, 1)) > 0 Then
TryAgain = False
Exit For
End If
Next
For i As Integer = 0 To ComboColumn.Items.Count - 1
If LCase(OtherGrass) = LCase(ComboColumn.Items.Item(i).ToString) Then
TryAgain = True
System.Windows.Forms.MessageBox.Show("This plant has already been added.")
End If
Next
End While
'ReDim Preserve Grasses(Grasses.GetUpperBound(0) + 1)
'Grasses(Grasses.GetUpperBound(0)) = OtherGrass
ComboColumn.Items.Add(OtherGrass)
End If
If DataGridView1.CurrentRow.Cells(1).Value Is Nothing Then
DataGridView1.CurrentRow.Cells(1).Value = txtSpacMult.Text
End If
'If CB.SelectedItem.ToString <> "" Then
' For i As Integer = 1 To DataGridView1.Columns.Count - 2
' Dim temp As Boolean = Me.DataGridView1.Rows(DataGridView1.CurrentRow.Index).Cells(i).ReadOnly
' Me.DataGridView1.Rows(DataGridView1.CurrentRow.Index).Cells(i).ReadOnly = False
' temp = Me.DataGridView1.Rows(DataGridView1.CurrentRow.Index).Cells(i).ReadOnly
' Next
'End If
EnableRun()
Catch ex As Exception
System.Windows.Forms.MessageBox.Show(ex.Message)
End Try
End Sub
Instead of:
ComboColumn.Items.Add(OtherGrass)
Put:
CB.Items.RemoveAt(CB.Items.Count - 1)
CB.Items.Add(OtherGrass)
CB.Items.Add("Other")
CB.SelectedItem = OtherGrass
You should have the new plant added and selected, and the "Other" entry moved to the end.

label loop for next visual basic

Currently my code looks like this:
Private Sub btnMotivate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMotivate.Click
Dim intNumber As Integer
Dim strStudy As String = "Study!"
intNumber = InputBox("How many times do you want to be motivated? Please use numbers!")
If intNumber < 1 Then
MessageBox.Show("Please use a number from 1 - 10!")
End If
If intNumber > 10 Then
MessageBox.Show("Please use a number from 1 - 10!")
End If
> For intCounter = 1 To intNumber Step 1
lblMotivation.Text = strStudy
> Next
End Sub
As you can see, I have added a variable and the loop runs fine, but I need help phrasing the code so whatever number the user inputs, is the number of lines of "Study!" displayed. I have tried using the string but also using the label with Environment.NewLine hoping it would add a new line every time the loop runs
You are setting the label text to strStudy each time. This doesn't add to what's there already, it just replaces it.
You need to add strStudy to the text that already exists, something like this:
' start with an empty string
lblMotivation.Text = ""
For intCounter = 1 To intNumber Step 1
' append the study string and a newline
lblMotivation.Text = lblMotivation.Text & strStudy & Environment.NewLine
Next
Instead of using a TextBox, use a ListBox to display the word Study! n -times. It is also good practice not to instruct the user to do something, but prevent it in code. Also note how intNumber has been changed to *inp*Number As Object
Private Sub btnMotivate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnMotivate.Click
Dim inpNumber As Object
Dim strStudy As String = "Study!"
Dim intCounter As Integer
inpNumber = InputBox("How many times do you want to be motivated?")
If Not IsNumeric(inpNumber) Then
MessageBox.Show("Please enter a number!")
ElseIf inpNumber < 1 OrElse inpNumber > 10 Then
MessageBox.Show("Please enter a number from 1 - 10!")
Else
ListBox1.Items.Clear()
For intCounter = 1 To inpNumber Step 1
ListBox1.Items.Add(strStudy)
Next
End If
End Sub