Adding multiple pictureboxes to a form programmatically in vb.net - vb.net

So I have written a short section of code to add 6 pictureboxes to a form in random locations. It adds each picturebox to a collection, then loops through the collection and adds them to the form control. The bizarre issue is that the code only works when I step through it line by line in debug mode. If I just compile and run the code then only 1 picturebox is added to the form, but if I step through the code line by line then all 6 pictureboxes are successfully added to the form in random locations. Can anyone tell me why the hell this happening? It's driving me pretty nuts. Code below:
For i As Integer = 0 To 5
Dim pic As New PictureBox
Dim rnd As New Random
pic.Location = New Point(rnd.Next(200, 300), rnd.Next(200, 300))
pic.Size = New Size(5, 5)
pic.BackColor = Color.White
pic.Visible = True
pic.BringToFront()
_picCollection.Add(pic)
Next
For Each item As PictureBox In _picCollection
Controls.Add(item)
Next
ShowDialog()
Open to suggestions of how to do this better / in a way that actually works properly.

Had to declare RND object outside of loop. Thanks tinstaafl!

Related

vb.net winform picturebox in a tabcontrol getting error message when trying to load image

As per the title, have a picturebox in a tabcontrol.
I can load an image in a PictureBox if it is not a member of the tabcontrol but as soon as I add it to the tabcontrol I get an error in the design window
BC30456: 'FromFile" is not a member of tabpage
code is:
Me.PictureBox1.Image = image.FromFile("c:\tmp\01_front.png")
What am I doing wrong?
This is driving me crazy.
Stopped and did something else for 5 minutes and thought my way through the answer that I have been hamming at for 1hr.
Create the control and then add it to the tabcontrol. I was still thinking in the vb 6 way.
Dim test = New PictureBox
Dim tp = TabControl1.TabPages(3)
test.Name = "picture"
With test
.Location = New Point(tp.Location)
.Size = New Size(tp.Width, tp.Height)
.SizeMode = PictureBoxSizeMode.StretchImage
.Image = Drawing.Image.FromFile("c:\tmp\01.png")
.SendToBack()
End With
tp.Controls.Add(test)

Image won't change in picturebox, vb.net

I'm trying to code it so that i can create a picture box from a method in a class. However when my picture box is drawn it doesn't display any image, it only shows a white square of the specified dimensions in the specified location.
Here is the code which i am using to create said picture box:
Public Sub DrawEnemy(ByRef formInstance)
Dim enemypic As New PictureBox
enemypic.Image = Image.FromFile("C:\fboi1\Enemy.Png")
enemypic.Width = 64
enemypic.Height = 64
enemypic.Location = New Point(Me.EnemyPosX, EnemyPosY)
enemypic.Visible = True
formInstance.Controls.Add(enemypic)
End Sub
And here is where i am calling the method from:
Dim Enemy1 As New computerControlled(1, 1)
Enemy1.DrawEnemy(Me)
Please add the following code in your DrawEnemy() method:
enemypic.SizeMode = PictureBoxSizeMode.StretchImage
When i drag the console window suddenly the white box turns into the image i wanted.
Aha! This means the code is not causing the form to be repainted. We can trigger that by calling the Invalidate() function.
Public Sub DrawEnemy(formInstance As Form)
Dim enemypic As New PictureBox
enemypic.Image = Image.FromFile("C:\fboi1\Enemy.Png")
enemypic.Width = 64
enemypic.Height = 64
enemypic.Location = New Point(Me.EnemyPosX, EnemyPosY)
enemypic.Visible = True
formInstance.Controls.Add(enemypic)
formInstance.Invalidate()
End Sub
If you're calling this several times in a loop, you would instead handle this after the loop, where you also block repainting (to prevent flickering) until the loop is finished.
form.SuspendLayout()
For Each enemy In ...
'...
DrawEnemy(form)
Next
form.Invalidate()
form.ResumeLayout()
It's also possible you only need to Invalidate() the picturebox.

System.Drawing.Pen - lines disappear when Labels are placed on Form

I want to draw TextBoxes/Labels on my form in code and connect them with lines - based on data that I have stored in a datatable ("treedata"). If I use the following code everything works fine:
For i = 0 To treedata.Rows.Count - 1
Dim tb As New TextBox
hor = treedata.Rows(i)(11)
vern = ver + 120 * treedata.Rows(i)(4)
tb.Text = "sometext"
tb.Location = New Point(hor, vern)
Form8.Controls.Add(tb)
posofmodif = treedata.Rows(i)(10)
vero = treedata.Rows(i)(6)
Dim myPen As New System.Drawing.Pen(System.Drawing.Color.Green)
Dim formGraphics As System.Drawing.Graphics
myPen.SetLineCap(LineCap.RoundAnchor, LineCap.ArrowAnchor, DashCap.Flat)
formGraphics = Form8.CreateGraphics()
formGraphics.DrawLine(myPen, Convert.ToSingle(posofmodif), Convert.ToSingle(vero), Convert.ToSingle(hor), Convert.ToSingle(vern))
myPen.Dispose()
formGraphics.Dispose()
Next
However I would like to use labels instead of TextBoxes because it makes no sense to use heavier TextBoxes in this case. But when I simply replace
Dim tb As New TextBox
by
Dim tb As New Label
the labels do appear on the Form as expected but the lines connecting them appear only for a moment and then turn invisible.
I first thought that the problem might be caused by labels being over or below the lines but even when I make sure that no line is crossing any label it happens.
Does anyone have an idea what I could do to avoid this?
This is your problem: Form8.CreateGraphics(). That method is volatile, as it creates a Graphics instance that does not survive the scope in which it's used.
You need to be using the Paint event for whatever control on which you intend to draw. The form, the label...whatever that is. The Paint event provides a Graphics object for you to use, and it gets called whenever the drawing needs to be refreshed.
Because the event fires frequently, you need to be mindful of what you do there. Heavy lifting in a Paint handler can slow an app down considerably.

Why don't my Labels show in VB.NET Form

After reading this question, I wrote some code to create a label for each attribute of an xml element.
The problem is that when I run the project, my form only displays the first label. I've checked in the immediate window as well as debug window and all of the labels are loaded to the form, but none of them are displayed. Help?
Here's the code that runs when the form loads.
Dim doc As New XmlDocument()
doc.Load("xmlfile")
Dim ability As XmlNode = doc.GetElementsByTagName("ability").Item(0)
Dim numberofLabels = ability.Attributes.Count
ReDim labels(numberofLabels)
For counter As Integer = 0 To numberofLabels - 1
labels(counter) = New Label
labels(counter).Visible = True
labels(counter).Text = ability.Attributes.Item(counter).Name
labels(counter).Location = New System.Drawing.Point(10, 30 + counter * 10)
Me.Controls.Add(labels(counter))
Next
You should be using some layout manager, to help you with control positioning. Doing it manually is not worth the pain. Try using TableLayoutPanel or FlowLayoutPanel. Both can be docked or anchored to a parent control, so everything behaves very smoothly. Otherwise you are looking to write a lot of positioning/resizing code, and then maintaining it later.
Change the value of 10 in the original code line for a new point to a bigger value such as 40, so that new labels could appear separated visually:
labels(counter).Location = New System.Drawing.Point(10 + counter, 30 + counter * 40)

Dynamic PictureBox in Visual Basic

I've created a form with a PictureBox on it and would like to dynamically create another PictureBox on the form while the program runs (to the left of the static one). I've written this code:
Dim temp As PictureBox
temp = New PictureBox
temp.Image = StaticPictureBox.Image
temp.Visible = True
temp.Top = StaticPictureBox.Top
temp.Width = StaticPictureBox.Width
temp.Height = StaticPictureBox.Height
temp.Left = StaticPictureBox.Left - 20
temp.BringToFront()
When I run this code I can detect that the temp PictureBox does get created. However, it is not rendered onto the form. It seems like it's there but is invisible.
Does anyone have an idea of what I'm doing wrong?
You need to add it to the form's control collection:
Me.Controls.Add(temp)
Why don't you just remove that code and place a picturebox next to the other one and set:
newpicturebox.visible = false
Then whenever you have the action completed you have it change:
newpicturebox.visible = true
I know this is old but... you got an error here:
temp.Left = StaticPictureBox.Left - 20
should be:
temp.Left = StaticPictureBox.right + 20
or:
temp.Left = StaticPictureBox.right
hope it helped.