循环遍历 VB.NET 中的控件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11166323/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Looping through Controls in VB.NET
提问by Rohit Shinde
I am creating a chess program. And it is composed of sixty four picture boxes with alternating black and white background colours.
I have named them pba1
, pba2
, pbb1
, pbb2
, pbc1
and so on.
Now, I want to loop through only the black ones, for example, I want to loop through only, pba1, pbb2, pbc3 and so on.
How do I create a loop for this in VB.NET?
我正在创建一个国际象棋程序。它由六十四个图片框组成,背景颜色为黑白交替。
我已经将它们命名为pba1
,pba2
,pbb1
,pbb2
,pbc1
等。
现在,我只想遍历黑色的,例如,我只想遍历 pba1、pbb2、pbc3 等等。
如何在 VB.NET 中为此创建循环?
I know of the way to loop through similarly named controls, but I am not able to adapt that method for my problem. Can you tell me a solution?
我知道循环遍历类似命名的控件的方法,但我无法针对我的问题调整该方法。你能告诉我一个解决方案吗?
EDIT: In pba1, pb stands for picture box, and a1 stands for the square. Just in case, you wonder why such a name.
编辑:在 pba1 中,pb 代表图片框,a1 代表正方形。以防万一,你想知道为什么会有这样的名字。
EDIT: Check out this answer
编辑:看看这个答案
回答by Mark Hall
Loop through the PictureBox's in your ControlCollection and test for BackColor. I used the Form's ControlCollection, if they are in some other type of container control use that.
循环遍历 ControlCollection 中的 PictureBox 并测试 BackColor。我使用了 Form 的 ControlCollection,如果它们在其他类型的容器控件中使用。
For Each cntrl As Control In Me.Controls
If TypeOf cntrl Is PictureBox Then
If cntrl.BackColor = Color.Black Then
'Do Something
End If
End If
Next
Base on the additional information that you gave in your answer, the reason your example is not working is that the Controls Name is a String and you are comparing it to the PictureBox Control not the Name of the Control.
根据您在答案中提供的其他信息,您的示例不起作用的原因是控件名称是一个字符串,并且您将它与图片框控件而不是控件的名称进行比较。
You can try using the Tag
Property instead of the Name
of the Control, it will be cleaner and easier to read. I just put a 1 in the PictureBox's Tag Property for Black and a 0 for White.
您可以尝试使用Tag
属性而不是Name
控件,它会更清晰、更易于阅读。我只是在 PictureBox 的 Tag 属性中为黑色设置 1,为白色设置 0。
Private Sub OriginalColour()
For Each cntrl As Control In Me.Controls
Dim result As Integer
If TypeOf cntrl Is PictureBox Then
If Integer.TryParse(cntrl.Tag.ToString, result) Then
If result = 1 Then
cntrl.BackColor = Color.Gray
Else
cntrl.BackColor = Color.White
End If
End If
End If
Next
End Sub
回答by Konrad Rudolph
Generating controls at design time via the Forms Designer only makes sense for layouts which benefit from the forms designer.
通过表单设计器在设计时生成控件仅对受益于表单设计器的布局有意义。
In your case, you just have 64 uniform boxes in 8 rows of 8. Don't use the Forms Designer for this, create the controls at runtime, and don't give them names like pba1
, just put them into an appropriate data structure (such as an 8x8 array):
在您的情况下,您只有 8 行 8 行中的 64 个统一框。不要为此使用表单设计器,在运行时创建控件,并且不要给它们命名,例如pba1
,只需将它们放入适当的数据结构中(例如 8x8 阵列):
Private chessFields As PictureBox(8, 8)
' In Form_Load:
For i = 0 To 7
For j = 0 To 7
chessFields(i, j) = New PictureBox
' Set size, position … then, finally,
Controls.Add(chessFields(i, j))
Next
Next
That way, you can access the fields in an orderly fashion without having to go via the Form.Controls
collection.
这样,您可以以有序的方式访问字段,而无需通过Form.Controls
集合。
回答by Rur
Put all the pictureboxes in an 8x8 tableLayoutPanel (also useful for scaling etc). Then
将所有图片框放在一个 8x8 的 tableLayoutPanel 中(对于缩放等也很有用)。然后
For Each pb As PictureBox In TableLayoutPanel1.Controls
Dim col As Integer = TableLayoutPanel1.GetCellPosition(pb).Column
Dim row As Integer = TableLayoutPanel1.GetCellPosition(pb).Row
If col Mod 2 = 0 Xor row Mod 2 = 0 Then
pb.BackColor = Color.Black
Else
pb.BackColor = Color.White
End If
Next
Of course you could also use an array of the squares if you have that available.
当然,如果您有可用的正方形数组,您也可以使用它。
This will not affect the events (pba1.click etc).
这不会影响事件(pba1.click 等)。
回答by Doug Harter
This is fairly simple and it may be resource heavy, but it works. I have a form with 36 CheckBoxes. This takes advantage of the fact that when you copy a checkbox it just increases the number of the name. I ended up with 36 checkboxes named CheckBox1 thru Checkbox36. The Function returns a checkbox, which may be used to set or read any property.
这相当简单,可能会占用大量资源,但它确实有效。我有一个包含 36 个复选框的表单。这利用了这样一个事实,即当您复制复选框时,它只会增加名称的数量。我最终得到了 36 个名为 CheckBox1 到 Checkbox36 的复选框。该函数返回一个复选框,可用于设置或读取任何属性。
Private Function GetCheckBox(ByVal Index As Integer) As CheckBox
Dim CKBox As checkbox
For Each cntrl As Control In Me.Controls
If TypeOf cntrl Is CheckBox Then
CKBox = cntrl
If CKBox.Name = "CheckBox" & Index Then
Exit For
End If
End If
Next
Return ckbox
End Function