我似乎记得遇到过类似的问题,如果记忆有用,诀窍是客观地从 for each 中删除表格,就像这样
Sub Butt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Butt.Click
Dim Forms As New List(Of Form)
Dim Pics As New Dictionary(Of Form, PictureBox)
Forms.Add(me)
Forms.Add(form2)
Forms.Add(form3)
Forms.Add(form4)
For x As Integer = 0 To Forms.Count - 1
If Not Pics.Contains(Forms(x), DirectCast(Me.Controls("PictureBox" + CStr(i + 1))(0), PictureBox)) Then
Pics.Add(Forms(x), DirectCast(Me.Controls("PictureBox" + CStr(i + 1))(0), PictureBox))
Else
Pics(Forms(x)) = DirectCast(Me.Controls("PictureBox" + CStr(i + 1))(0), PictureBox)
End If
Next
################################################# ###################################### 更新探索并扩展上述内容### ################################################# #########################
下面是对这个问题的更详细的解释和分解,以及为什么它实际上不是 .NET 中的神话或怪事
.NET OO 框架非常庞大复杂且功能强大,要理解和记住这一切并非人为不可能,但需要掌握一些概念才能在迷宫中导航。
让我们检查一下出了什么问题。
您用项目中的每个表单声明并填充了表单列表 List(Of Form)
Dim Forms as New List(Of Form)
然后,您声明了一个字典来保存形状(Form、PictureBox)的(键、值)集合
Dim Pics as New Dictionary(Of Form, PictureBox)
这意味着您的“Key”是 Form 类型,而您的“Value”是 PictureBox 类型
现在,使用您正在遍历列表中每个表单的表单列表,说您希望将Dictionary*(Pics)* 中“键” (表单)的“值” (图片框)设置为图片框在名称为“PictureBox(x)”的当前表单(代码正在运行的位置)上找到,其中 x 是某种增量整数值。奇怪的是,您然后要求该图片框的第一个实例(那是最后的 (0) 部分)
For Each frm As Form In Forms
pics(frm) = Me.Controls("PictureBox" + CStr(i + 1))(0)
Next
从根本上说,从 pics(frm) 调用的方法仅获取或设置字典中现有项目的值,因为字典尚未加载任何内容,Pics 是空的,您从未向字典中添加任何表单因此,根本不会设置任何内容。
实现键值分配的更合适的方法如下,但是简单地设置表单的背景图像仍然是矫枉过正的
Sub BuildDictionary()
'1. Declare the array of forms and the dictionary of (Key,Values) of type (Form,PictureBox)
Dim Forms As New List(Of Form) 'list of forms that you want to assign BG
Dim Pics As New Dictionary(Of Form, PictureBox) 'declare your dictionary list ("Key","Value") = (Form,Picturebox)
With Forms 'fill the list
.Add(Me)
.Add(Form1)
.Add(Form2)
.Add(Form3)
End With
'2. Snag the picturebox we want to assign to the forms
Dim PictureBoxToAssign As PictureBox = DirectCast(Me.Controls("PictureBox" + CStr(i + 1)), PictureBox) 'grab your picturebox
'3 option 1 (prefered)
'#### Either Do this next
Pics.Clear() 'if your logic allows that you can clear the dictionary first
For x As Integer = 0 To Forms.Count - 1 'for each form in the array
Pics.Add(Forms(x), PictureBoxToAssign) 'add the form and picturebox to the dictionary
Next
'3 option 2 (only if you cannot clear the dictionary)
'#### Or Do this
'you cannot clear the dictionary first due to logic
For x As Integer = 0 To Forms.Count - 1 'for each form in the array
'check existance of the pair
If Pics.Contains(New Generic.KeyValuePair(Of Form, PictureBox)(Forms(x), PictureBoxToAssign)) Then
Pics(Forms(x)) = PictureBoxToAssign 'update the value
Else
Pics.Add(Forms(x), PictureBoxToAssign) 'add the new pair
End If
Next
End Sub
如果目标只是将每个表单的背景图像设置为图片框的图像,那么可能更快更有效的路线可能是以下示例
Sub SetBG()
Dim Forms As Form() = {Me, Form1, Form2, Form3} 'array of forms that you want to assign BG, occupies less memory than a list
Dim PictureBoxToAssign As PictureBox = DirectCast(Me.Controls("PictureBox" + CStr(i + 1)), PictureBox) 'grab your picturebox
For x As Integer = 0 To Forms.Count - 1 'for each form in the array
Forms(x).BackgroundImage = PictureBoxToAssign.Image 'assign the image to the background
Next
End Sub
这里要记住的重要一点是,当以任何方式更改对象时,在遍历数组中的对象集合时,虽然可能,但不能使用“将每个 obj 作为对象数组中的类型”的方法来完成,即不像这样
For Each obj as ObjectType in ArrayofObjects
Change the properties of obj = (BIG NO CAN DO)
Next
您必须将循环与直接与集合中的对象交互分开,在本示例中,通过使用 for each 像这样的索引
For x As Integer = 0 To Forms.Count - 1 'using an integer not the object itself
'referencing the object through the index of the collection Forms(x)
Forms(x).BackgroundImage = PictureBoxToAssign.Image
Next
我希望这个答案能给黑暗带来光明