Reputation: 570
Ok let me explain my question, here I have a 4x4 array of picture boxes which looks like this:
C1 C2 C3 C4
Row 1: [] [] [] []
Row 2: [] [] [] []
Row 3: [] [] [] []
Row 4: [] [] [] []
When the user presses on one of the picture boxes the background color of the picture box changes. I am trying to iterate through each of the rows to figure out which pictures box's have a red background per row. The timer interval is set in Beats Per Minute (60000 / textbox1.text). How do I accomplish this? I made the 2d array but the iteration is not working.
Dim graph(4, 4) As PictureBox
graph(1, 1) = PictureBox1
graph(1, 2) = PictureBox2
graph(1, 3) = PictureBox3
graph(1, 4) = PictureBox4
graph(2, 1) = PictureBox5
graph(2, 2) = PictureBox6
graph(2, 3) = PictureBox7
graph(2, 4) = PictureBox8
graph(3, 1) = PictureBox9
graph(3, 2) = PictureBox10
graph(3, 3) = PictureBox11
graph(3, 4) = PictureBox12
graph(4, 1) = PictureBox13
graph(4, 2) = PictureBox14
graph(4, 3) = PictureBox15
graph(4, 4) = PictureBox16
Private Sub Button5_Click_1(sender As System.Object, e As System.EventArgs) Handles Button5.Click
Dim tempo As Integer = CInt(TextBox1.Text)
Dim BPM As Integer = 60000 / tempo
Timer1.Interval = BPM
Timer1.Enabled = True
End Sub
Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
For i As Integer = 1 To 4
Select Case i
Case 1
For value As Integer = 1 To 4
If graph(1, value).BackColor = Color.Red Then
MsgBox("sfd")
End If
Next
Case 2
For value As Integer = 1 To 4
If graph(2, value).BackColor = Color.Red Then
MsgBox("sfd")
End If
Next
Case 3
For value As Integer = 1 To 4
If graph(3, value).BackColor = Color.Red Then
MsgBox("sfd")
End If
Next
Case 4
For value As Integer = 1 To 4
If graph(4, value).BackColor = Color.Red Then
MsgBox("sfd")
End If
Next
Case Else
Debug.WriteLine("Not between 1 and 10, inclusive")
End Select
Next
End Sub
Private Sub PictureBox1_Click(sender As System.Object, e As System.EventArgs) Handles PictureBox1.Click
PictureBox1.BackColor = Color.Red
End Sub
Any Help is greatly appreciated. Thank you!
Upvotes: 0
Views: 1922
Reputation: 32607
Before I answer your question, here is some general advice regarding your code:
VB array indices are zero-based. An array Dim arr(4) As ...
declares an array with five elements (which can be accessed by index 0 through 4). Therefore, your array declaration of graph
creates an array with 25 elements when you only need 16. Such waste of memory should be avoided.
The creation of your graph could be automated. It's probably even a better idea to create all picture boxes automatically. This way, if you want to change the graph size, you just have to change a single number instead of a whole bunch of code. Similarly, the bounds of your for
loops should respect the actual array bounds instead of some pre-defined constants.
When you parse user input, you should handle incorrect input. Use Integer.TryParse()
instead of CInt()
.
As a beginner, you should turn Option Strict On
(via the project settings). This avoids narrowing implicit casts that you might not be aware of. E.g. it would tell you that 60000 / tempo
results in a Double
and by assigning that to an Integer
variable you will loose precision.
I suspect that you have similar click handlers for all picture boxes. If all handlers are doing the same work, use a single handler. The method's sender
argument tells you which picture box was clicked (you can cast it to the appropriate type).
Using a For
loop does not make any sense if you split the body according to the loop variable. If you do different work in every iteration, don't use a loop at all and just write the code snippets after each other. However, in your case, a loop makes sense, though not as you used it. See next section for more information.
Now to your question. If you want to gather the checked boxes per row, you should use two nested loops. The outer loops iterates the rows and the inner loop iterates columns. Before starting the inner loop, you should reset a buffer that holds the indices of the checked boxes. I use the corrected indices (0 through 3). Furthermore, I assume that the first index in the graph
array specifies the row and the second specifies the column. If that's wrong, you just have to swap the according pieces of code:
Dim checkedBoxes As New List(Of Integer) 'holds the indices of checked boxes in a row
For row As Integer = 0 To graph.GetUpperBound(0)
checkedBoxes.Clear()
For col As Integer = 0 To graph.GetUpperBound(1)
...
Next
'Now report the checked boxes.
MessageBox.Show("Checked boxes of row " & row & ":" & Environment.NewLine & _
String.Join(", ", checkedBoxes))
Next
The String.Join
method is used to concatenate the list of column indices to a single string, separated by ,
.
Now we just need to add code to the loop body that gathers the checked boxes:
If graph(row, col).BackColor = Color.Red Then
checkedBoxes.Add(col)
Next
That's all. No awkward Switch
statement, no duplicate code. There are still some improvements that could make this code more efficient, but I'll leave it with this for now.
Upvotes: 2
Reputation: 34
if you want two message boxes to appear at the same time, the only way would be to run them on different threads, ie after the conditional create a thread that runs the message box to keep the loop going. A message box will halt the code on that thread and waits for user input and the only way you can run 'msgbox()' at the same instant is with multiple threads. Otherwise what you are asking is impossible.
Upvotes: 0