Can I do this shorter from a single timer without needing 5 timers?
I can run it in a sub Timer1.Enabled = True, Timer1.Start () and can change according to preferences, timer2, timer3. so I want to do this to go shorter. I think I should have a case function, or something like that. how could i do it
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim strx As String
Dim stry As String
For i As Integer = 1 To 10
strx = TextBox1.Lines(i)
stry = TxtBoxIntDrawsY.Text
If stry.Contains(strx) = True Then
Exit For
RndTitaniumA1()
Else
Exit For
If TextBox4.Text = ("1") Then
BttRnd.PerformClick()
Else
RndTitaniumA2()
End If
End If
Next
Timer1.Stop()
Timer1.Enabled = False
End Sub
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
Dim strx As String
Dim stry As String
For i As Integer = 1 To 10
strx = TextBox1.Lines(i)
stry = TxtBoxIntDrawsY.Text
If stry.Contains(strx) = True Then
Exit For
RndTitaniumA1()
Else
Exit For
If TextBox4.Text = ("2") Then
BttRnd.PerformClick()
Else
RndTitaniumA3()
End If
End If
Next
Timer2.Stop()
Timer2.Enabled = False
End Sub
Private Sub Timer3_Tick(sender As Object, e As EventArgs) Handles Timer3.Tick
Dim strx As String
Dim stry As String
For i As Integer = 1 To 10
strx = TextBox1.Lines(i)
stry = TxtBoxIntDrawsY.Text
If stry.Contains(strx) = True Then
Exit For
RndTitaniumA1()
Else
Exit For
If TextBox4.Text = ("3") Then
BttRnd.PerformClick()
Else
RndTitaniumA4()
End If
End If
Next
Timer3.Stop()
Timer3.Enabled = False
End Sub
Private Sub Timer4_Tick(sender As Object, e As EventArgs) Handles Timer4.Tick
Dim strx As String
Dim stry As String
For i As Integer = 1 To 10
strx = TextBox1.Lines(i)
stry = TxtBoxIntDrawsY.Text
If stry.Contains(strx) = True Then
Exit For
RndTitaniumA1()
Else
Exit For
If TextBox4.Text = ("4") Then
BttRnd.PerformClick()
Else
RndTitaniumA5()
End If
End If
Next
Timer4.Stop()
Timer4.Enabled = False
End Sub
Private Sub Timer5_Tick(sender As Object, e As EventArgs) Handles Timer5.Tick
Dim strx As String
Dim stry As String
For i As Integer = 1 To 10
strx = TextBox1.Lines(i)
stry = TxtBoxIntDrawsY.Text
If stry.Contains(strx) = True Then
Exit For
RndTitaniumA1()
Else
Exit For
If TextBox4.Text = ("5") Then
BttRnd.PerformClick()
Else
MsgBox("")
End If
End If
Next
Timer5.Stop()
Timer5.Enabled = False
End Sub
Let's start with your answers to my questions.
Array indexes in .net start at zero. If you have 10 lines in your textbox, you will get an index out of range exception with For i As Integer = 1 To 10 because there is no index 10. The indexes run from 0 to 9. I still don't see how you are preventing the user from deleting a few lines.
It won't run because you have preceded the code with Exit For. When the code reaches that line it exits the For loop and goes immediately to TimerX.Stop().
Private Sub OpCode()
For i = 0 To 10
Exit For
MessageBox.Show(i.ToString)
Next
End Sub
The MessageBox in the above code will never be displayed. Even if you repositioned the Exit For, you have the exit in both the If block and the Else block so the code would only survive one iteration.
You still didn't answer if the code works as written or why you are using a For loop at all and leaving the loop on the first iteration. Also, the mysterious empty MsgBox and why there are 5 timers.
You can add a break point and step through your code.
Notice the Handles clause in the .Tick event. This event now handles all the Timers.
I used a Select Case as suggested by #preciousbetine in comments. Since a Timer is a component it has no Name property (what I would normally use in the Select Case) so, I used the Is operator. I could also have set the .Tag property for each Timer and used that. I left in the Exit For (repositioned) but be aware; you will only get a single iteration.
Calling an event in code can have unanticipated effects. I showed you how to move the code from the button click to a separate Sub and then call it from the .Click and your routine.
Private Sub AnyTimer_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick, Timer2.Tick, Timer3.Tick, Timer4.Tick, Timer5.Tick
Dim t As System.Windows.Forms.Timer = DirectCast(sender, System.Windows.Forms.Timer)
Dim strx As String
Dim stry As String
stry = TxtBoxIntDrawsY.Text
For i As Integer = 0 To 9
strx = TextBox1.Lines(i)
If stry.Contains(strx) = True Then
RndTitaniumA1()
Exit For
Else
Dim TextBox4Contents As String = ""
Select Case True
Case t Is Timer1
TextBox4Contents = "1"
Case t Is Timer2
TextBox4Contents = "2"
Case t Is Timer3
TextBox4Contents = "3"
Case t Is Timer4
TextBox4Contents = "4"
Case t Is Timer5
TextBox4Contents = "5"
End Select
If TextBox4.Text = TextBox4Contents Then
RndSub()
Else
Select Case True
Case t Is Timer1
RndTitaniumA2()
Case t Is Timer2
RndTitaniumA3()
Case t Is Timer3
RndTitaniumA4()
Case t Is Timer4
RndTitaniumA5()
Case t Is Timer5
MsgBox("") '???
Case Else
MessageBox.Show("Sender does not match any Timer")
Return
End Select
End If
Exit For
End If
Next
t.Stop()
t.Enabled = False
End Sub
Private Sub BttnRnd_Click(sender As Object, e As EventArgs) Handles BttnRnd.Click
RndSub()
End Sub
Private Sub RndSub()
'Your button code here
End Sub
Related
Code is below. I'm trying to compare a user input string with a large listbox and if it finds a match, it terminates the loop and prints a response. I keep getting hung up with it freezing or printing the wrong response.
Private Sub btnAction_Click(sender As Object, e As EventArgs) Handles btnAction.Click
Dim input As String = txtIn.Text
Dim i As Integer = 0
While i <= lstRoseBowl.Items.Count - 1
If input = CStr(lstBox.Items(i)) Then
txtOut.Text = "Yes"
Else
txtOut.Text = "No"
End If
End While
End Sub
You need to increment "i"
Private Sub btnAction_Click(sender As Object, e As EventArgs) Handles btnAction.Click
Dim input As String = txtIn.Text
Dim i As Integer = 0
While i <= lstRoseBowl.Items.Count - 1
If input = CStr(lstBox.Items(i)) Then
txtOut.Text = "Yes"
Else
txtOut.Text = "No"
End If
i += 1 ' <-----
End While
End Sub
Or better yet, use a for loop
Private Sub btnAction_Click(sender As Object, e As EventArgs) Handles btnAction.Click
Dim input As String = txtIn.Text
For i As Integer = 0 To lstRoseBowl.Items.Count - 1
If input = CStr(lstBox.Items(i)) Then
txtOut.Text = "Yes"
Else
txtOut.Text = "No"
End If
Next
End Sub
Now, this will compile and run but might not give you the result you want since if it find the items on the first try, it would then display No on the second try. There are better ways of doing it but for the least amount of code change, it could look like this.
Private Sub btnAction_Click(sender As Object, e As EventArgs) Handles btnAction.Click
Dim input As String = txtIn.Text
txtOut.Text = "No"
For i As Integer = 0 To lstRoseBowl.Items.Count - 1
If input = CStr(lstBox.Items(i)) Then
txtOut.Text = "Yes"
Exit For
End If
Next
End Sub
In my code, when TextBox3 does not have any value, it must show a notice in a MsgBox to enter a value in TextBox1
But when I run it the MsgBoxnotice appears twice in the screen when it should show only once.
Here is my code:
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
If TextBox3.Text = Nothing Then
TextBox1.Clear()
MsgBox("Enter Number to Textbox1")
Else
Dim digit As Integer = CInt(TextBox3.Text)
If TextBox1.TextLength = digit Then
Dim fields() As String = ListBox1.Text.Split(";")
Dim idx As Integer = ListBox1.FindString(TextBox1.Text)
If idx <> -1 Then
ListBox1.SelectedIndex = idx
ListBox1.SelectedIndex.ToString(fields(0))
ListBox2.Items.Add(Now() + Space(1) + ListBox1.Text.Substring(0, 13))
PrintDocument1.Print()
Else
TextBox1.Clear()
End If
End If
End If
End Sub
The Issue here is that the event handler gets triggered another time because clearing the textbox1 equals the textbox1_changed event handler to go of. You could as well just disable the textbox till the textbox3 is not nothing anymore.
or a quick solution would be aswell
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
If not TextBox1.Text = Nothing AndAlso TextBox3.text = Nothing Then
TextBox1.Clear()
MsgBox("Enter Number to Textbox1")
.............
You are using the wrong event. Textchanged triggers when you clear the textbox as well resulting in two messageboxes.
Use LostFocus instead
Here is the solution,
Public Class Form1
Dim message as boolean = true
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs) Handles TextBox1.TextChanged
If TextBox3.Text = Nothing Then
If message Then 'show the message as true
message = False 'set the message false for textbox_changed not appear again
Textbox1.Clear()
message = True 'set the message true for next time textbox change appear again
MsgBox("Enter Number to Textbox3")
End If
Else
Dim digit As Integer = CInt(TextBox3.Text)
If TextBox1.TextLength = digit Then
Dim fields() As String = ListBox1.Text.Split(";")
Dim idx As Integer = ListBox1.FindString(TextBox1.Text)
If idx <> -1 Then
ListBox1.SelectedIndex = idx
ListBox1.SelectedIndex.ToString(fields(0))
ListBox2.Items.Add(Now() + Space(1) + ListBox1.Text.Substring(0, 13))
PrintDocument1.Print()
Else
TextBox1.Clear()
End If
End If
End If
End Sub
This is a slot machine program. I am trying to detect how many times the user clicks a button (spins). But I can't figure out why my counter only adding 1 to my clickLabel? I'm sure it's a simple fix but I'm drawing a blank.
Public Class MainForm
Private Sub clickHereButton_Click(sender As Object, e As EventArgs) Handles clickHereButton.Click
' simulates a slot machine
Dim randGen As New Random
Dim leftIndex As Integer
Dim centerIndex As Integer
Dim rightIndex As Integer
Dim counter As Integer = 1
clickHereButton.Enabled = False
For spins As Integer = 1 To 10
leftIndex = randGen.Next(0, 6)
leftPictureBox.Image = ImageList1.Images.Item(leftIndex)
Me.Refresh()
System.Threading.Thread.Sleep(50)
centerIndex = randGen.Next(0, 6)
centerPictureBox.Image = ImageList1.Images.Item(centerIndex)
Me.Refresh()
System.Threading.Thread.Sleep(50)
rightIndex = randGen.Next(0, 6)
rightPictureBox.Image = ImageList1.Images.Item(rightIndex)
Me.Refresh()
System.Threading.Thread.Sleep(50)
Next spins
If leftIndex = centerIndex AndAlso
leftIndex = rightIndex Then
MessageBox.Show("Congratulations!", "Winner", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
counter += 1
clickLabel.Text = counter.ToString()
clickHereButton.Enabled = True
clickHereButton.Focus()
End Sub
Private Sub exitButton_Click(sender As Object, e As EventArgs) Handles exitButton.Click
Me.Close()
End Sub
End Class
What's happening is you're always setting the counter to 1 everytime you click the button because it is inside the clickHereButton_Click. So even though you are incrementing it, at the beginning of your sub you are still setting it to 1.
Dim counter As Integer = 1
Private Sub clickHereButton_Click(sender As Object, e As EventArgs) Handles clickHereButton.Click
...
End Sub
Alright, so the program is set up where you have a set of radio buttons with 5 states, and another set of 5 with 5 capitals. There's a button which tells you if they match or not. However I have to do it a certain way where clicking a radio button assigns a variable to both 'strCapital' and 'strChoice' and you compare them to see if they match.
I've tried to figure everything out (since it sounds easy in theory) but I've hit a wall.
Option Explicit On
Option Strict On
Option Infer Off
Public Class frmMain
Dim strCapital As String
Dim strChoice As String
Dim strLittleRock As String
Dim strSpringfield As String
Dim strFrankfort As String
Dim strSalem As String
Dim strMadison As String
Private Sub radArkansas_CheckedChanged(sender As Object, e As EventArgs) Handles radArkansas.CheckedChanged
strCapital = strLittleRock
End Sub
Private Sub radIllinois_CheckedChanged(sender As Object, e As EventArgs) Handles radIllinois.CheckedChanged
strCapital = strSpringfield
End Sub
Private Sub radSpringfield_CheckedChanged(sender As Object, e As EventArgs) Handles radSpringfield.CheckedChanged
strChoice = strSpringfield
End Sub
Private Sub btnVerify_Click(sender As Object, e As EventArgs) Handles btnVerify.Click
If strCapital = strChoice Then
lblMsg.Text = "Correct"
ElseIf strCapital <> strChoice Then
lblMsg.Text = "Incorrect"
End If
End Sub
Private Sub radLittleRock_CheckedChanged(sender As Object, e As EventArgs) Handles
radLittleRock.CheckedChanged
strChoice = strLittleRock
End Sub
End Class
EDIT: Also I forgot to mention the main problem which is always a bad thing. Basically whenever I run it and enter something incorrect (checking Arkansas and Springfield for example) it always says it's correct.
I did something similar... you can modify this code:
Private Sub btnAmIRight_Click(sender As Object, e As EventArgs) Handles btnAmIRight.Click
' displays if submission is correct
' declare variables
Dim strAmIRight As String
Dim dblMatch As Double
If rbtnAlabama.Checked = True And rbtnMontgomery.Checked = True Then
dblMatch = 1
ElseIf rbtnAlaska.Checked = True And rbtnJuneau.Checked = True Then
dblMatch = 1
ElseIf rbtnArizona.Checked = True And rbtnPhoenix.Checked = True Then
dblMatch = 1
ElseIf rbtnArkansas.Checked = True And rbtnLittleRock.Checked = True Then
dblMatch = 1
ElseIf rbtnCalifornia.Checked = True And rbtnSacramento.Checked = True Then
dblMatch = 1
ElseIf rbtnColorado.Checked = True And rbtnDenver.Checked = True Then
dblMatch = 1
ElseIf rbtnConnecticut.Checked = True And rbtnHartford.Checked = True Then
dblMatch = 1
ElseIf rbtnDelaware.Checked = True And rbtnDover.Checked = True Then
dblMatch = 1
ElseIf rbtnFlorida.Checked = True And rbtnTallahassee.Checked = True Then
dblMatch = 1
ElseIf rbtnGeorgia.Checked = True And rbtnAtlanta.Checked = True Then
dblMatch = 1
Else
dblMatch = 0
End If
' assign code to variable
If dblMatch = 1 Then
strAmIRight = "Correct"
ElseIf dblMatch = 0 Then
strAmIRight = "Try Again"
End If
' display result
lblResult.Text = strAmIRight.ToString
End Sub
So I need a button to complete two operations but in two steps. Here is the first buttons code:
First button (button6)
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
p = Process.GetProcessesByName("SbieSvc")
If p.Count > 0 Then
Environment.Exit(0)
Else
End If
Dim antiProcess() As String = {"SbieSvc", "Sandboxiecrypto", "sbiectrl"}
For intI As Integer = 0 To antiProcess.GetUpperBound(0)
For Each x As Process In Process.GetProcessesByName(antiProcess(intI))
x.Kill()
Next
Next
''Sets the Channel''
If TextBox6.Text = "" Then
MsgBox("Please enter a Channelname!", MsgBoxStyle.Information, ("Error"))
GoTo Bottom
End If
Me.Data = Me.TextBox6.Text
Me.Method_1(String.Format("Channel set ({0})", Data))
If (Me.thread0 Is Nothing) Then
Me.thread0 = New Thread(New ThreadStart(AddressOf Method2)) With
{
.IsBackground = True
}
Me.thread0.Start()
End If
''Part Of Grab Urls Method''
Button6.Enabled = False
For i As Integer = 0 To TextBox5.Text Step 1
Dim t1 As New Thread(New ParameterizedThreadStart(Sub() GetUrls(TextBox6.Text)))
t1.Start()
Next
GC.SuppressFinalize(Me)
End Sub
Second button (button1)
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
''start live viewers''
Button1.Enabled = False
For Each itemss In Urls.Items
Dim t1 As New Threading.Thread(Sub() LivePeepz(itemss))
t1.Start()
Next
End Sub
How would I make this code so that button6 will complete it's normal commands, then once done it begins button1's operation. I thought about doing this;
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
p = Process.GetProcessesByName("SbieSvc")
If p.Count > 0 Then
Environment.Exit(0)
Else
End If
Dim antiProcess() As String = {"SbieSvc", "Sandboxiecrypto", "sbiectrl"}
For intI As Integer = 0 To antiProcess.GetUpperBound(0)
For Each x As Process In Process.GetProcessesByName(antiProcess(intI))
x.Kill()
Next
Next
''Sets the Channel''
If TextBox6.Text = "" Then
MsgBox("Please enter a Channelname!", MsgBoxStyle.Information, ("Error"))
GoTo Bottom
End If
Me.Data = Me.TextBox6.Text
Me.Method_1(String.Format("Channel set ({0})", Data))
If (Me.thread0 Is Nothing) Then
Me.thread0 = New Thread(New ThreadStart(AddressOf Method2)) With
{
.IsBackground = True
}
Me.thread0.Start()
End If
''Part Of Grab Urls Method''
Button6.Enabled = False
For i As Integer = 0 To TextBox5.Text Step 1
Dim t1 As New Thread(New ParameterizedThreadStart(Sub() GetUrls(TextBox6.Text)))
t1.Start()
Next
GC.SuppressFinalize(Me)
''start live viewers''
Button1.Enabled = False
For Each itemss In Urls.Items
Dim t1 As New Threading.Thread(Sub() LivePeepz(itemss))
t1.Start()
End Sub
But this doesn't work...Any ideas? Thanks. VB2012
Put your code in seperate functions e.g. Function1 would contain the code you intended for first button click. Function2 would have the code intended for second button click.
Then you have one button with an onClick event code that is
Private Sub Button1_Click(byVal sender as Object, byVal e as EventArgs) Handles Button1.Click
Function1()
Function2()
End Sub
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
FirstOperation()
SecondOperation()
End Sub
Private Sub FirstOperation()
'Button 6 Code
End Sub
Private Sub SecondOperation()
'Button 1 Code
End Sub