{"id":4681,"date":"2014-03-30T14:42:01","date_gmt":"2014-03-30T14:42:01","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2014\/03\/30\/vb-net-for-each-iterates-only-once-over-a-list-collection-of-common-programming-errors\/"},"modified":"2014-03-30T14:42:01","modified_gmt":"2014-03-30T14:42:01","slug":"vb-net-for-each-iterates-only-once-over-a-list-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2014\/03\/30\/vb-net-for-each-iterates-only-once-over-a-list-collection-of-common-programming-errors\/","title":{"rendered":"vb.net &ldquo;For Each&rdquo; iterates only once over a list-Collection of common programming errors"},"content":{"rendered":"<p>I seem to remember running into a similar issue, the trick if memory serves is to remove the form objectively from the for each like so<\/p>\n<pre><code>Sub Butt_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles     Butt.Click\nDim Forms As New List(Of Form)\nDim Pics As New Dictionary(Of Form, PictureBox)\nForms.Add(me)\nForms.Add(form2)\nForms.Add(form3)\nForms.Add(form4)\n\nFor x As Integer = 0 To Forms.Count - 1\n    If Not Pics.Contains(Forms(x), DirectCast(Me.Controls(\"PictureBox\" + CStr(i + 1))(0), PictureBox)) Then\n            Pics.Add(Forms(x), DirectCast(Me.Controls(\"PictureBox\" + CStr(i + 1))(0), PictureBox))\n        Else\n            Pics(Forms(x)) = DirectCast(Me.Controls(\"PictureBox\" + CStr(i + 1))(0), PictureBox)\n        End If\nNext\n<\/code><\/pre>\n<p><strong>########################################################################################## UPDATE explore and expand on the above ##############################################################################<\/strong><\/p>\n<p><strong>What follows is a more detailed explanation and break down of this problem and why it isn&#8217;t actually a myth or an oddity in .NET<\/strong><\/p>\n<p>The .NET OO framework is incredibly large complex and powerful, to understand and remember it all is not humanly impossible, but there are a few concepts that need to be grasped in order to navigate your way through the maze.<\/p>\n<p>Lets examine what was going wrong.<\/p>\n<p>You declared and populated a List of forms <em>List(Of Form)<\/em> with each form in your project<\/p>\n<pre><code>Dim Forms as New List(Of Form)\n<\/code><\/pre>\n<p>You then declared a dictionary to hold a (key, value) collection of the shape (Form, PictureBox)<\/p>\n<pre><code>Dim Pics as New Dictionary(Of Form, PictureBox)\n<\/code><\/pre>\n<p>This means your &#8220;Key&#8221; is of type Form and your &#8220;Value&#8221; is of type PictureBox<\/p>\n<p>Now, using the list of Forms you were iterating through each form in the list, saying that you want the &#8220;Value&#8221;<em>(PictureBox)<\/em> of the &#8220;Key&#8221;<em>(Form)<\/em> in the Dictionary*(Pics)* to be set to a PictureBox found on the current form <em>(Where the code is running)<\/em> with name &#8220;PictureBox(x)&#8221; where x is your incremental integer value of some kind. Strangely you are then asking for the first instance of something of that picturebox <em>(thats the (0) part on the end)<\/em><\/p>\n<pre><code>For Each frm As Form In Forms\n    pics(frm) = Me.Controls(\"PictureBox\" + CStr(i + 1))(0)\nNext\n<\/code><\/pre>\n<p><strong>Fundamentally the method invoked from pics(frm) only gets or sets the value of an existing item in the dictionary, since the dictionary is not loaded with anything yet, Pics is empty, at no point did you add any of the forms to the Dictionary and as such nothing would be set at all.<\/strong><\/p>\n<p>A more suitable approach to achieve the Key Value assignment would be as follows, however this is still overkill to simply set the background image of the forms<\/p>\n<pre><code>Sub BuildDictionary()\n    '1. Declare the array of forms and the dictionary of (Key,Values) of type (Form,PictureBox)\n    Dim Forms As New List(Of Form) 'list of forms that you want to assign BG\n    Dim Pics As New Dictionary(Of Form, PictureBox) 'declare your dictionary list (\"Key\",\"Value\") = (Form,Picturebox)\n    With Forms 'fill the list\n        .Add(Me)\n        .Add(Form1)\n        .Add(Form2)\n        .Add(Form3)\n    End With\n\n    '2. Snag the picturebox we want to assign to the forms\n    Dim PictureBoxToAssign As PictureBox = DirectCast(Me.Controls(\"PictureBox\" + CStr(i + 1)), PictureBox) 'grab your picturebox\n\n    '3 option 1 (prefered)\n    '#### Either Do this next\n    Pics.Clear() 'if your logic allows that you can clear the dictionary first\n    For x As Integer = 0 To Forms.Count - 1 'for each form in the array\n        Pics.Add(Forms(x), PictureBoxToAssign) 'add the form and picturebox to the dictionary            \n    Next\n\n    '3 option 2 (only if you cannot clear the dictionary)\n    '#### Or Do this\n    'you cannot clear the dictionary first due to logic\n    For x As Integer = 0 To Forms.Count - 1 'for each form in the array\n        'check existance of the pair\n        If Pics.Contains(New Generic.KeyValuePair(Of Form, PictureBox)(Forms(x), PictureBoxToAssign)) Then\n            Pics(Forms(x)) = PictureBoxToAssign 'update the value \n        Else\n            Pics.Add(Forms(x), PictureBoxToAssign) 'add the new pair\n        End If\n    Next\nEnd Sub\n<\/code><\/pre>\n<p>If the objective is merely to set the background image of each form to the image of a picturebox, then perhaps a faster more efficient route might be the following example<\/p>\n<pre><code>Sub SetBG()\n    Dim Forms As Form() = {Me, Form1, Form2, Form3} 'array of forms that you want to assign BG, occupies less memory than a list\n    Dim PictureBoxToAssign As PictureBox = DirectCast(Me.Controls(\"PictureBox\" + CStr(i + 1)), PictureBox) 'grab your picturebox\n    For x As Integer = 0 To Forms.Count - 1 'for each form in the array\n        Forms(x).BackgroundImage = PictureBoxToAssign.Image 'assign the image to the background      \n    Next\nEnd Sub\n<\/code><\/pre>\n<p><em><strong>The important thing to remember here is that when changing the object in any way, while iterating through the collection of objects within the array, while possible, must NOT be done using a &#8220;for each obj as type in array of object&#8221; approach, ie not like this<\/strong><\/em><\/p>\n<pre><code>For Each obj as ObjectType in ArrayofObjects\n    Change the properties of obj = (BIG NO CAN DO)\nNext\n<\/code><\/pre>\n<p>you <strong>MUST<\/strong> separate the loop from interacting directly with the object in collection, in this example by using the for each of an index like so<\/p>\n<pre><code>For x As Integer = 0 To Forms.Count - 1 'using an integer not the object itself\n    'referencing the object through the index of the collection Forms(x)\n    Forms(x).BackgroundImage = PictureBoxToAssign.Image \nNext\n<\/code><\/pre>\n<p>I hope this answer brings light to the darkness<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I seem to remember running into a similar issue, the trick if memory serves is to remove the form objectively from the for each like so 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 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-4681","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/4681","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=4681"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/4681\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=4681"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=4681"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=4681"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}