好的,让我解释一下我的问题,这里有一个4x4的图片框,看起来像这样:
C1 C2 C3 C4
Row 1: [] [] [] []
Row 2: [] [] [] []
Row 3: [] [] [] []
Row 4: [] [] [] []
当用户按下其中一个图片框时,图片框的背景颜色会发生变化。我试图遍历每一行,以确定哪些图片框每行有一个红色背景。计时器间隔设置为每分钟节拍数(60000 / textbox1.text)。我该如何做到这一点?我制作了2d数组,但迭代不起作用。
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
非常感谢任何帮助。谢谢!
答案 0 :(得分:2)
在回答您的问题之前,以下是有关您的代码的一般性建议:
VB数组索引从零开始。数组Dim arr(4) As ...
声明一个包含五个元素的数组(可以通过索引0到4访问)。因此,当您只需要16时,graph
的数组声明会创建一个包含25个元素的数组。应该避免这种内存浪费。
您的图表的创建可以自动化。自动创建所有图片框甚至可能更好。这样,如果要更改图形大小,只需更改一个数字而不是一大堆代码。类似地,for
循环的边界应该遵循实际的数组边界而不是一些预定义的常量。
解析用户输入时,应该处理错误的输入。使用Integer.TryParse()
代替CInt()
。
作为初学者,您应该转动Option Strict On
(通过项目设置)。这可以避免缩小您可能不知道的隐式转换。例如。它会告诉您60000 / tempo
会产生Double
,并且通过将其分配给Integer
变量,您将失去精确度。
我怀疑你有适用于所有图片框的点击处理程序。如果所有处理程序都在执行相同的工作,请使用单个处理程序。方法的sender
参数告诉您单击了哪个图片框(您可以将其转换为适当的类型)。
如果根据循环变量拆分正文,则使用For
循环没有任何意义。如果你在每次迭代中做不同的工作,根本不要使用循环,只需在彼此之后编写代码片段。但是,在你的情况下,循环是有意义的,虽然不是你使用它。有关详细信息,请参阅下一节。
现在回答你的问题。如果要收集每行的复选框,则应使用两个嵌套循环。外循环迭代行,内循环迭代列。在启动内部循环之前,您应该重置一个包含复选框索引的缓冲区。我使用校正的索引(0到3)。此外,我假设graph
数组中的第一个索引指定行,第二个索引指定列。如果这是错的,你只需要交换相应的代码:
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
String.Join
方法用于将列索引列表连接到单个字符串,以,
分隔。
现在我们只需要将代码添加到收集复选框的循环体中:
If graph(row, col).BackColor = Color.Red Then
checkedBoxes.Add(col)
Next
这就是全部。没有笨拙的Switch
语句,没有重复的代码。仍然有一些改进可以使这个代码更有效率,但我现在就把它留下来。
答案 1 :(得分:0)
如果你想同时出现两个消息框,唯一的办法就是在不同的线程上运行它们,即在条件创建一个运行消息框的线程后保持循环运行。一个消息框将暂停该线程上的代码并等待用户输入,并且在同一时刻运行'msgbox()'的唯一方法是使用多个线程。否则你所要求的是不可能的。