Memory Game click events and random number generator - arrays

So I am building a Memory Game. This is a 2 part question. I have 16 boxes being used and need to have the numbers 1-8 twice. I have set up each box as a structure and have a random number generator randomly picking a number for a box and then randomly placing a number 1 - 8 into it. Problem I am coming across is this. I am getting repeat numbers for my boxes and more than 2 times for a digit that will be placed in that box, sometimes no sequential number being used all together. How can I make sure all 16 boxes are being created with out having to make code for 16 different instances. Also need to make sure each single digit number between 1-8 is being used and only used twice?
Second part of my question is I am having an issue with making a click event when a user chooses a box. Right now I can't figure out how to associate which box the user clicks on. I don't want to write code for 16 different boxes, link an array to each box and then populate each box that array's guess number. Is there a way I can simplify that code down to something short?
I have included all the code so far.
Option Strict On
Option Explicit On
Option Infer Off
Public Class Form1
Structure MemoryBox
Public intBox As Integer
Public intGuess As Integer
Public strGuess As String
End Structure
Private gameScore() As Integer
Private memoryGame(15) As MemoryBox
Dim countLoad As Integer = 0
Dim countScore As Integer = 0
Dim intScore As Integer
Private Sub LoadGame()
'this is where I am using the random numbers to make each box and populate it with a guess
Dim randomGen As New Random
Dim intMemBox As Integer
Dim intMemGuess As Integer
intScore = 0
If countLoad <= 15 Then
intMemBox = randomGen.Next(1, 16)
intMemGuess = randomGen.Next(1, 8)
memoryGame(countLoad).intBox = intMemBox
memoryGame(countLoad).intGuess = intMemGuess
memoryGame(countLoad).strGuess = intMemGuess.ToString
countLoad += 1
End If
End Sub
Private Sub GuessClick()
'trying to use this area for click event for each box click
lblMemory1.BackColor = Color.Green
lblMemory1.Text = memoryGame()
intScore += 1
lblScore.Text = intScore.ToString
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Call LoadGame()
End Sub
Private Sub btnNewGame_Click(sender As Object, e As EventArgs) Handles btnNewGame.Click
gameScore(countScore) = intScore
countScore += 1
Dim outFile As IO.StreamWriter
outFile = IO.File.AppendText("score.txt")
outFile.WriteLine(intScore)
outFile.Close()
Call LoadGame()
End Sub
Private Sub btnHighScore_Click(sender As Object, e As EventArgs) Handles btnHighScore.Click
Array.Sort(gameScore)
lblHighScore.Text = gameScore(0).ToString
End Sub
Private Sub btnAllScores_Click(sender As Object, e As EventArgs) Handles btnAllScores.Click
Dim inFile As IO.StreamReader
Dim strInfo As String
If IO.File.Exists("score.txt") Then
inFile = IO.File.OpenText("score.txt")
Do Until inFile.Peek = -1
strInfo = inFile.ReadLine
Loop
inFile.Close()
Else
MessageBox.Show("Can't find the score.txt file", "High Score", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
MessageBox.Show(strInfo, "All Scores", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
End Class

One option is to populate an array with the numbers you want, then randomly shuffle it. Use a loop that runs at least one times the length of the array and use the iterator value as one index and swap it with a randomly chosen index.
Something like this:
Dim memoryGame(15) As MemoryBox
Dim randomarray() As Integer = {1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8}
Dim rnd As New Random(Now.Millisecond)
For I = 0 To 15
Dim randindex As Integer = rnd.Next(0, 16)
Dim temp As Integer = randomarray(I)
randomarray(I) = randomarray(randindex)
randomarray(randindex) = temp
Next
For I = 0 To 15
memoryGame(I).intBox = randomarray(I)
Next
From here simply iterate through the array and assign the values to your boxes
To handle the click events:
Use the same handler for each box. One way is to add a Handles clause for each box. With 16 boxes this could get a little clunky. I would suggest in the load event handler iterate through the boxes and use the AddHandler statement to add the handler to each box. At this point sender will always point to the box that was clicked. It is simply a matter of casting sender as whatever type the box is, to access all the properties of the box.
If the boxes are buttons(Box1, Box2, etc.) it would look something like this:
For Each b As Button In Me.Controls.OfType(Of Button).Where(Function(x) x.Name.StartsWith("Box"))
AddHandler b.Click, AddressOf Button_Click
Next
Private Sub Button_Click(sender As Object, e As EventArgs)
Dim clickedbutton As Button = DirectCast(sender, Button)
'access the properties here
End Sub

Related

Visual Basic code works but is inelegant - any suggestions?

I am trying to stay ahead of my Year 12 Software class. Starting to work with records and arrays. I have answered the question, but the solution feels very clunky. I am hoping someone has suggestions/links for completing this task in a more efficient way.
The task: read in lines from a text file and into a structure, and then loop through that, populating four list boxes if an animal hasn't been vaccinated.
Here's the code:
Imports System.IO
Public Class Form1
'Set up the variables - customer record, total pets not vaccinated, total records in the file, and a streamreader for the file.
Structure PetsRecord
Dim custName As String
Dim address As String
Dim petType As String
Dim vacced As String
End Structure
Dim totNotVac As Integer
Dim totalRecCount As Integer
Dim PetFile As IO.StreamReader
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub btnLoad_Click(sender As Object, e As EventArgs) Handles btnLoad.Click
'set an array of records to store each record as it comes in. Limitation: you need to know how many records in the file. Set the array at 15 to allow for adding more in later.
Dim PetArray(15) As PetsRecord
'variables that let me read in a line and split it into sections.
Dim lineoftext As String
Dim i As Integer
Dim arytextfile() As String
'tell them what text file to read
PetFile = New IO.StreamReader("patients.txt")
totNotVac = 0
Try
totalRecCount = 0
' read each line in and split the lines into fields for the records. Then assign the fields from the array. Finally, reset the array and loop.
Do Until PetFile.Peek = -1
'read in a line of text
lineoftext = PetFile.ReadLine()
'split that line into bits separated by commas. these will go into the array.
arytextfile = lineoftext.Split(",")
'dunno whether this is the best way to do it, but stick the array bits into the record, and then clear the array to start again.
PetArray(totalRecCount).custName = arytextfile(0)
PetArray(totalRecCount).address = arytextfile(1)
PetArray(totalRecCount).petType = arytextfile(2)
PetArray(totalRecCount).vacced = arytextfile(3)
totalRecCount += 1
Array.Clear(arytextfile, 0, arytextfile.Length)
Loop
For i = 0 To PetArray.GetUpperBound(0)
If PetArray(i).vacced = "No" Then
lstVaccinated.Items.Add(PetArray(i).vacced)
lstCustomer.Items.Add(PetArray(i).custName)
lstAddress.Items.Add(PetArray(i).address)
lstPetType.Items.Add(PetArray(i).petType)
totNotVac += 1
lblVacTotal.Text = "The total number of unvaccinated animals is " & CStr(totNotVac)
End If
Next
Catch ex As Exception
MsgBox("Something went wrong with the file")
End Try
PetFile.Close()
End Sub
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Close()
End Sub
End Class
And one line from the patient.txt file:
Richard Gere,16 Sunset Blvd,Gerbil,No
I hope this isn't out of place.
Regards,
Damian
If you want to use Streams be aware that they need to be disposed.
File.ReadAllLines returns an array of lines. Since the array is initialized where it is declared we don't need to specify a size.
If you use List(Of T) you do not have to know in advance the number of elements in the list. Avoids the limitation of array.
Using a For Each avoids having to use the size. The small c following "," tells the compiler that this is a Char which is what .Split is expecting. If you had Option Strict On, which you always should, you would have seen an error. You add items to the list by creating a New PetsRecord. The parametrized Sub New receives the values and sets the properties.
Don't change the display in the label on each iteration. Use an interpolated string (preceded by a $) which allows embedded variables surrounded by braces { }. It is not necessary to change the number to a string as it is implied by the interpolator. (Available in VS2015 and later)
Public Structure PetsRecord
Public Property custName As String
Public Property address As String
Public Property petType As String
Public Property vacced As String
Public Sub New(name As String, add As String, pType As String, vac As String)
custName = name
address = add
petType = pType
vacced = vac
End Sub
End Structure
Private Sub btnLoad_Click(sender As Object, e As EventArgs) Handles btnLoad.Click
Dim lines = File.ReadAllLines("patients.txt")
Dim lstPet As New List(Of PetsRecord)
For Each line In lines
Dim splits = line.Split(","c)
lstPet.Add(New PetsRecord(splits(0), splits(1), splits(2), splits(3)))
Next
Dim totNotVac As Integer
For Each pet In lstPet
If pet.vacced = "No" Then
lstVaccinated.Items.Add(pet.vacced)
lstCustomer.Items.Add(pet.custName)
lstAddress.Items.Add(pet.address)
lstPetType.Items.Add(pet.petType)
totNotVac += 1
End If
Next
lblVacTotal.Text = $"The total number of unvaccinated animals is {totNotVac}"
End Sub
If you don't need the 'PetsRecord' array to store data, take a look at the following code:
Dim totNotVac As Integer
Private Sub btnLoad_Click(sender As Object, e As EventArgs) Handles btnLoad.Click
File.ReadAllLines("your text file path").ToList().ForEach(Sub(x)
lstVaccinated.Items.Add(x.Split(","c)(0))
lstCustomer.Items.Add(x.Split(","c)(1))
lstAddress.Items.Add(x.Split(","c)(2))
lstPetType.Items.Add(x.Split(","c)(3))
totNotVac += 1
End Sub)
lblVacTotal.Text = "The total number of unvaccinated animals is " & CStr(totNotVac)
End Sub

How to monitor array's and reset when limit is reached. VB.net

I have a VB.Net program that loops through array's to try to figure out where bottles are on a "conveyor". The point of this program is to visually show staff, how the conveyor works using VB.net and Labels. It's extremely difficult to explain, so I’ll do my best.
Bottle_Number(10) Bottle_Position(128)
There are 10 bottles that I want to track at all 128 stops on the conveyor.
We have a conveyor that can only fit 10 bottles. I need to track the position of each of the 10 bottles. Once bottle 11 comes on - That means bottle 1 is completed and off the conveyor. So, bottle 11 becomes bottle 1, so I need to reset the position of bottle1 to 0, and continue tracking bottles 2-9 while also tracking bottle 11(Not bottle 1). Once bottle 12 comes on it becomes bottle 2, and I need to reset the position of bottle 2 to '0' and continue tracking all bottles.
Any help would be appreciated.
Here is my code:
Public Class frmMain
Dim Product_Position(10) As Integer
Dim Inches_Per_Pulse As Integer
Dim PulseNumber As Integer
Dim Product_Counter As Integer
Dim Product_Location(10) As Integer
Dim Function1 As Integer
Dim Function2 As Integer
Dim Function3 As Integer
Dim Function4 As Integer
Dim Function5 As Integer
Dim Function6 As Integer
Dim Function7 As Integer
Dim Function8 As Integer
Dim Function9 As Integer
Dim Function10 As Integer
Dim Product_in_Tunel As Integer
Dim test As Integer
Dim Roll_OVer As Boolean
Dim Product_Counter_Test As Integer
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
lblStatus.BackColor = Color.Green
lblStatus.Text = "Conveyor Status: Running"
End Sub
Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
lblStatus.BackColor = Color.Red
lblStatus.Text = "Conveyor Status: Off"
End Sub
Private replace_next As Integer
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
If Product_Counter = 10 Then
replace_next += 1
If replace_next > 10 Then
replace_next = 1 ' replace them in turn 1..10, then loop back to 1
Product_Position(replace_next) = 0 ' put initial position here
End If
End If
Product_Counter = Product_Counter + 1
If Product_Counter > 10 Then
Product_Counter = 1
Roll_over = True
End If
'MsgBox(Product_Counter)
'MsgBox(replace_next)
End Sub
Private Sub btnPulse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPulse.Click
Get_Location()
End Sub
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
PulseNumber = "0"
Inches_Per_Pulse = "1"
Roll_OVer = False
'MsgBox("Test")
End Sub
Public Sub Get_Location()
'MsgBox(Product_Counter)
If Roll_OVer = True Then
Product_Counter_Test = 10
'MsgBox("i'm stuck here")
End If
If Roll_OVer = False Then
Product_Counter_Test = Product_Counter
End If
'MsgBox(Product_Counter_Test)
'MsgBox("am I here - Yes")
For test = 1 To Product_Counter_Test
'MsgBox("This works")
Product_Position(test) = Product_Position(test) + Inches_Per_Pulse
Next
PulseNumber = PulseNumber + 1
ClearLabels()
lblProduct1Position.Text = Product_Position(1)
lblProduct2Position.Text = Product_Position(2)
lblProduct3Position.Text = Product_Position(3)
lblProduct4Position.Text = Product_Position(4)
lblProduct5Position.Text = Product_Position(5)
lblProduct6Position.Text = Product_Position(6)
lblProduct7Position.Text = Product_Position(7)
lblProduct8Position.Text = Product_Position(8)
lblProduct9Position.Text = Product_Position(9)
lblProduct10Position.Text = Product_Position(10)
End Sub
Public Sub ClearLabels()
lblProduct1Position.Text = ""
lblProduct2Position.Text = ""
lblProduct3Position.Text = ""
lblProduct4Position.Text = ""
lblProduct5Position.Text = ""
lblProduct6Position.Text = ""
lblProduct7Position.Text = ""
lblProduct8Position.Text = ""
lblProduct9Position.Text = ""
lblProduct10Position.Text = ""
End Sub
The Pulse button is what is actually driving the conveyor, each pulse (click of the button) means the conveyor is moving forward.
Right now once the program gets to bottle 11, it resets and only moves forward the "new" bottle (bottle1). It should continue incrementing the remaining bottles until they reach the end and do the same for them - Reset the position to 0 and begin counting again.
As far as I understand it, once you have 11 bottles, you don't want to reset to only one bottle, but instead still have 10 bottles, and replace one of them. You'll need a second variable to keep track of which is to be replaced.
So instead of :
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
Product_Counter = Product_Counter + 1
If Product_Counter > 10 Then Product_Counter = 1
End Sub
It would be something like:
Private Replace_Next as Integer = 0
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
If Product_Counter = 10 Then
Replace_Next += 1
If Replace_Next > 10 Then Replace_Next = 1 ' replace them in turn 1..10, then loop back to 1
Product_Position(Replace_Next) = .... ' put initial position here
Else
Product_Counter = Product_Counter + 1
End If
End Sub
Your conveyor is FIFO (first-in, first-out), so rather than constantly shifting, reindexing and/or rebuilding (=reset?) an array to make it seem like it is FIFO, Net includes the Queue(Of T) collection which is FIFO.
A LinkedList(Of T) could also be used. A plain List(Of T) would also work, but if the add/remove frequency is high, that will result in the same inefficient shifting taking place under the hood that you have with an array.
The only issue is enforcement of the size limit, which is easily handled with a small class wrapper. I assume there is something interesting or identifiable about the bottles other than their position. The test code uses a sequence ID and the contents.
Friend Class Bottle
Public Property Contents As String
Public Property SequenceID As Int32
' etc
Public Overrides Function ToString() As String
Return String.Format("{0}: ({1})", SequenceID.ToString("00"), Contents)
End Function
End Class
You likely have more relevant information to show. The, the collection class:
Friend Class BottleQueue
Private mcol As Queue(Of Bottle)
Private lbls As Label()
Private MaxSize As Int32 = 10 ' default
Public Sub New(size As Int32)
MaxSize = size
mcol = New Queue(Of Bottle)
End Sub
Public Sub New(size As Int32, l As Label())
Me.New(size)
lbls = l
End Sub
Public Sub Add(b As Bottle)
mcol.Enqueue(b)
Do Until mcol.Count <= MaxSize
mcol.Dequeue()
Loop
UpdateDisplay()
End Sub
Public Function Peek() As Bottle
Return mcol.ElementAtOrDefault(0)
End Function
Public ReadOnly Property Count() As Int32
Get
Return mcol.Count
End Get
End Property
Public Function Remove() As Bottle
Dim b As Bottle = Nothing
If mcol.Count > 0 Then
b = mcol.Dequeue
UpdateDisplay()
End If
Return b
End Function
Private Sub UpdateDisplay()
Dim n As Int32
If lbls Is Nothing OrElse lbls.Count = 0 Then
Return
End If
For n = 0 To mcol.Count - 1
lbls(n).Text = mcol.ElementAtOrDefault(n).ToString
Next
For n = n To lbls.Count - 1
lbls(n).Text = "(empty)"
Next
End Sub
Public ReadOnly Property GetQueue As Bottle()
Get
Return mcol.ToArray()
End Get
End Property
End Class
The class has 2 display means built in. One updates a set of labels. Since it is a collection, it also provides a way to get the current collection in order for a collection type control such as a Listbox. An even better way would be if the collection itself was "observable", so it could be used as a datasource.
It also provides a way to Removethe next bottle manually. Removing from a specific index (e.g. Remove(3)) is antithetical to a Queue, so it isnt implemented.
test code:
' form level vars:
Private BottleQ As BottleQueue
Private BottleID As Int32 = 7
' form load, passing the labels to use
' using a queue size of FIVE for test
BottleQ = New BottleQueue(5, New Label() {Label1, Label2, Label3, Label4, Label5})
Adding an item:
Dim material = {"Napalm", "Beer", "Perfume", "Pepsi", "Cyanide", "Wine"}
' add new bottle with something in it
BottleQ.Add(New Bottle With {.Contents = material(RNG.Next(0, material.Count)),
.SequenceID = BottleID})
BottleID += 1
' clear and show the contents in a listbox:
lbQueView.Items.Clear()
lbQueView.Items.AddRange(BottleQ.GetQueue)
The BottleId arbitrarily starts at 7, the contents are random. BTW, material shows just about the only way I ever use an array: when the contents are fixed and known ahead of time. In almost all other cases, a NET collection of one sort or another, is probably a better choice.
Because it is not an observable collection (and that is a little at odds with the FIFO nature), the listbox needs to be cleared each time. That could be internal to the class like the label display is. Results:
On the right, the first 5 are shown in order; 3 clicks later, the result is on the left: everything moved up 3 and 3 new items have been added.
Note: If the code using this needs to know when/which Bottle is removed from the conveyor, the class could include a ItemRemoved event which provides the item/Bottle just removed when adding forces one out. That is probably the case, but the question doesnt mention it.

How to respond to events for objects in an array

I have made an array of tiles (pictureboxes) in an array and need them to all do something when clicked, but don't know how. Specifically, I want to be able to place some other object on them by clicking a tile and making that object go to that tile's location. I know you may suggest looking at the mouseposition variable and having some invisible box over all the tiles to register clicks, but I would like to know how to register any event for an object in an array for anything that comes up in the future. I do know how to register events for objects which aren't in an array by the way.
The object I want to move on top of the picturebox will also be from an object array, but a different one.
Here is my code:
Public Class Form1
Dim tiles(50) As PictureBox 'This is the object array of tiles
Dim plants() As String 'I haven't set this up yet, but this will be for the objects to be 'placed' on the pictureboxes.
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim tileWidth As Integer = 50
Dim tileHeight As Integer = 50
Dim xindent As Integer = 10
Dim yindent As Integer = 10
For x = 0 To 9
For y = 0 To 4
ReDim Preserve tiles(x * y)
tiles(x * y) = New PictureBox With {.Visible = True, .Size = New System.Drawing.Size(50, 50), .Parent = Me, .BackColor = Color.GreenYellow, .Image = Nothing}
tiles(x * y).Location = New System.Drawing.Point(x * tileWidth + xindent, y * tileHeight + yindent)
If (x Mod 2 = 0 And y Mod 2 = 0) Or (x Mod 2 <> 0 And y Mod 2 <> 0) Then
tiles(x * y).BackColor = Color.Green
End If
Next
Next
End Sub
End Class
I simply don't know how to set up the click event handler for the array of tiles so that's why its not in the code above.
Thanks in advance for your help.
AddHandler is there for that. After the New you just need to attach a function to the event
AddHandler tiles(x * y).Click, AddressOf Tile_Click
And have a function that handles the event
Private Sub Tile_Click(sender As Object, e As System.EventArgs)
' sender represent the reference to the picture box that was clicked
End Sub
If you already know the size of the array, you should ReDim your array just once instead of each time you loop (Move the ReDim out of the loops). Also, since y is 0 on the first loop, you are basically doing a ReDim of 0 elements (x*y = 0 when y = 0)
the_lotus has already given you a great answer.
Just wanted to share a trick I often use when wiring up events with AddHandler.
Declare a temporary variable using WithEvents in your class:
Public Class Form1
Private WithEvents Tile As PictureBox
...
Now, in the two DropDowns across the top of code editor, change Form1 to Tile, and (Declarations) to Click (or whatever event you want). This will enter a method for you that has the correct method signature:
Private Sub Tile_Click(sender As Object, e As EventArgs) Handles Tile.Click
End Sub
Delete the Handles Tile.Click portion that appears at the end of the first line:
Private Sub Tile_Click(sender As Object, e As EventArgs)
End Sub
Finally, remove your temporary declaration that used WithEvents.
Now you've got a method with the correct signature that you can use with AddHandler. This is very handy for events that don't have the standard signature.

Visual Basic - use parallel arrays for displaying shipping charges based on input entered by user

I really stink at using arrays. I have this working with a 2 dimensional array but cannot figure out how to get it working with parallel one dimensional arrays. The Display Shipping button's Click even should display a shipping charge based on the number of items entered by the user. I am storing the minimum order amounts and shipping charges in parallel arrays. I cannot get the calculations to work correctly. Any help is appreciated.
Public Class frmMain
'declare parallel arrays
Private strNums() As String = {"1", "11", "51", "101"}
Private intShipping() As Integer = {15, 10, 5, 0}
Private Sub btnExit_Click(sender As Object, e As EventArgs) Handles btnExit.Click
Me.Close()
End Sub
Private Sub txtordered_KeyPress(sender As Object, e As KeyPressEventArgs) Handles txtOrdered.KeyPress
' allows the text box to accept numbers and the Backspace key
If (e.KeyChar < "0" OrElse e.KeyChar > "9") AndAlso e.KeyChar <> ControlChars.Back Then
e.Handled = True
End If
End Sub
Private Sub txtordered_TextChanged(sender As Object, e As EventArgs) Handles txtOrdered.TextChanged
lblShipping.Text = String.Empty
End Sub
Private Sub btnDisplay_Click(sender As Object, e As EventArgs) Handles btnDisplay.Click
'displays the shipping price based on orders
Dim strSearchForNum As Integer
Dim intSub As Integer
Integer.TryParse(txtOrdered.Text, strSearchForNum)
'search the array for the orders greater than zero
'if less than zero show error message
'otherwise display shipping charge
Do Until intSub >= strNums.Length OrElse
strSearchForNum >= CDbl(strNums(intSub))
intSub += 1
Loop
If strSearchForNum = 0 Then
MessageBox.Show("Please enter a number greater than 0", "Number of Orders")
Else
lblShipping.Text = intShipping(intSub).ToString("C2")
End If
txtOrdered.Focus()
End Sub
End Class

Saving nameless textboxes into Database in VB.NET

I'm a student currently doing my programming coursework. I have created a piece of code which creates text boxes for the user to input the names of tracks from a vinyl. As you can choose the amount of text boxes you create, these text boxes end up not having a name (e.g. textbox1, textbox2...), this makes me unsure of how to send the values of the textboxes to the database table. The table is currently empty and only has one column. Could someone please let me know how I will send these values to the database and also the code to create a new column for the tracks. Here is my current code below:
Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Label11.Show()
GroupBox1.Show()
GroupBox1.AutoSize = True
Dim number As Integer
number = TextBox8.Text
Dim boxes(number) As TextBox
Dim newbox As TextBox
For i As Integer = 1 To number
newbox = New TextBox
newbox.Size = New Drawing.Size(100, 20)
newbox.Location = New Point(10, 10 + 25 * (i - 1))
AddHandler newbox.TextChanged, AddressOf TextBox_TextChanged
boxes(i) = newbox
GroupBox1.Controls.Add(newbox)
newbox.Name = ("Trackbox" & i)
Next
End Sub
Your boxes array needs to be declared at form level.
Private boxes() As TextBox
Private Sub Button1_Click_1(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Label11.Show()
GroupBox1.Show()
GroupBox1.AutoSize = True
Dim number As Integer
'need to insert validation code here to make sure a number is entered in TextBox8
number = Integer.Parse(TextBox8.Text)
ReDim boxes(number)
Dim newbox As TextBox
For i As Integer = 1 To number
newbox = New TextBox
newbox.Size = New Drawing.Size(100, 20)
newbox.Location = New Point(10, 10 + 25 * (i - 1))
AddHandler newbox.TextChanged, AddressOf TextBox_TextChanged
GroupBox1.Controls.Add(newbox)
newbox.Name = ("Trackbox" & i.ToString)
boxes(i) = newbox
Next
End Sub
Then you can reference your text boxes as follows:
MessageBox.Show(boxes(5).Text)

Resources