programmably create picturebox inside panel - vb.net

Hey all i have created a panel that i want to place a lot of pictureboxes inside of. I will be pulling pictures from the "my pictures" folder. I am wanting to have 3 pictureboxes per row.
My current code is this:
Dim newPictureBox As New PictureBox
newPictureBox.Image = Image.FromFile("C:\Users\Public\Pictures\Sample Pictures\Lighthouse.jpg")
newPictureBox.Visible = True
newPictureBox.Top = 0 'needed calulation here for each picturebox
newPictureBox.Left = 0 'needed calulation here for each picturebox
newPictureBox.Width = 536
newPictureBox.Height = 338
newPictureBox.BackgroundImageLayout = ImageLayout.Stretch
Panel1.Controls.Add(newPictureBox)
That does just fine for the first picturebox inside the panel but i will be looping an unknown number of pictures that need pictureboxes to go with it. I know the next picturebox should have a Left value of 545 but i am unsure of how to calcualte that out? Then the top calculations for the second row, third row, etc...
What would the process be for getting the correct Top, Left coordinates for each picturebox so that it only has 3 pictureboxes in each row?

Related

Displaying images from a picturebox list

I am trying to display a line of pictures in my program. But I am having a problem, where it is only showing the first image in the imagelist and only showing one image-box.
Private Cards As New List(Of PictureBox)
Private Sub SetupCards()
For i As Integer = 0 To imglist1.Images.Count - 1
Dim PicCard As PictureBox = New PictureBox()
PicCard.Width = 100
PicCard.Height = 200
PicCard.Top = 50
PicCard.Left = 50
Me.Controls.Add(PicCard)
PicCard.Image = imglist1.Images(i)
Cards.Add(PicCard)
Next i
End Sub
You're placing the picture boxes on top of each other, which is why you only see the last card. You've got to set a different Left property for every picture box you add.
The solution is rather simple. Just add the picture box's width to Left, multiplied by the current index i.
PicCard.Left = 50 + PicCard.Width * i
Don't need to keep the imaging controls in your own list if you add them to a parent container control.
Use ListView or third-party controls, or use custom drawing code if you need to use ListBox (which wraps respective Windows control). See
C# Can I display images in a list box?

Location properties on winforms acting strange

I have a form where I allow the user to generate multiple panels with some various contents in the panels by pressing an "add" button. Depending on what the user does in the panel, the panel grows and shrinks to fit the contents. Because of this change is size, I have created a sub that formats the panels on the form.
Private Sub formatPanels(frm As Form)
Dim count As Integer = 0
Dim startPoint As Point = New Point(12, 80)
Dim endPoint As Point = New Point(0, 0)
Dim maxY As Integer = 0
For Each pnl As Control In frm.Controls
If TypeOf pnl Is Panel Then
ReDim Preserve _arr_Panels(count)
_arr_Panels(count) = pnl
count += 1
pnl.Location = startPoint
startPoint.Y += pnl.Size.Height + 30
End If
Next
End Sub
So as you can see, we loop through every panel and the first always begins at the location (12,80) and then increments with the size of the panel and some spacing.
HERE IS THE ISSUE. This ONLY happens when i am SCROLLED DOWN the form. The panels spacing all of a sudden screws up and decides to put the first panel hundreds of pixels down the form. Is the location property based on what you're looking at? So if I were scrolled down the form location(0,0) would be the top left of the current view? There must be some weird property to location that I am not aware of.
Thanks
This behavior is not related to a panel, but to any control on a form with AutoScroll = True and Anchor including Top. (Note: if Anchor didn't also include Left I had some strange positioning on the first call of the function.
The solution is described here which is to use AutoScrollPosition. If you change your startPoint to this it will adjust for the scroll position.
Dim startPoint As Point = New Point(12, Me.AutoScrollPosition.Y + 80)
And the documentation for AutoScrollPosition states this:
When adding controls programmatically to a form, use the AutoScrollPosition property to position the control either inside or outside of the current viewable scroll area.

For each getting all picture boxes

Building a space invaders game framework and having some issues getting each bullet that's on screen.
The bullet is defined/created using the below :
Dim Bullet As PictureBox
Bullet = New PictureBox()
Controls.Add(Bullet)
For Each Bullet As Control In Me.Controls
If TypeOf Bullet Is PictureBox Then
If Bullet.Visible = True Then
BulletTimer.Enabled = True
Bullet.Top = Bullet.Top - 10
End If
End If
Next
The problem I've got is that this gets every picture box on screen, including the player and enemies and sends the whole lot flying upwards rather than just the bullets.
You can use the Tag property present in every control. Set the Tag property of the PictureBox to something that identify your PictureBox as a bullet. For example you can set it to the string "BULLET".
Then your loop checks if the PictureBox has the Tag set and if the Tag property has the value "BULLET"
Dim Bullet As PictureBox
Bullet = New PictureBox()
Bullet.Tag = "BULLET"
Controls.Add(Bullet)
....
For Each Bullet As PictureBox In Me.Controls.OfType(Of PictureBox)
If Bullet.Tag IsNot Nothing AndAlso Bullet.Tag.ToString = "BULLET" Then
If Bullet.Visible = True Then
BulletTimer.Enabled = True
Bullet.Top = Bullet.Top - 10
End If
End If
Next
Notice that you can simplify your loop using the OfType(T) extension to retrieve only PictureBox from the controls collection. This remove the need to check if the control is a PictureBox.

Accessing multiple PictureBoxes (or any form control) in Visual Basic?

So I'm making a game in VB for learning purposes and now I'm struggling with this problem:
I'm trying to do a For loop that draws the level map. However, I just can't seem to figure out it. This is an example of what I'm trying to do:
For index as integer = 1 to 192
PictureBox(index).Image = bg(map(x,y)) 'this is causing me problems
x=x+1
if x=16 then
x=0
y=y+1
End If
Next
But since PictureBox(index).Image doesn't seem to be the correct answer, it simply throws me an error.
Is there any way to do this?
EDIT:
Shortly, I need to set PictureBox.Image's from 1 to 192 like this without having 192 lines of code:
PictureBox1.Image = bg(map(0,0))
PictureBox2.Image = bg(map(1,0))
PictureBox3.Image = bg(map(2,0))
PictureBox4.Image = bg(map(3,0))
'etc....
Instead I wan't to set them in a For loop. I don't want to have extra lines of code.
EDIT2:
The PictureBoxes are added in the editor.
In the designer set the property Tag of each PictureBox to the string value composed by the x and y required to pass to the map function
For example:
PictureBox1 should have the Tag property set to "0,0"
PictureBox2 set the Tag property to "1,0",
....
PictureBox17 will have the Tag property set to "0,1"
and so on until you have mapped all your pictureboxes with the correct values.
Then your code could be changed to
' Assuming the PictureBox are all childs of the Form
For Each pic in Me.Controls.OfType(Of PictureBox)()
Dim tag = pic.Tag
' You could omit this check if you have only the pictureboxes
' set with a valid Tag property
if Not string.IsNullOrEmpty(tag) Then
Dim xyCoords = tag.ToString().Split(","c)
pic.Image = bg(map(Convert.ToInt32(xyCoords(0),
Convert.ToInt32(xyCoords(1))))
End if
Next
I'm going to make a huge assumption here and assume that you already have the PictureBox's on the form prior to reaching this code and they have Id's PictureBox1 through PictureBox192. The code would look like the following. You need to:
1. Retrieve the element by its ID
2. Cast/convert it from an object to a PictureBox
3. Set it's Image property appropriately.
Dim pBox As PictureBox ' To store each pic box in
For index as integer = 1 to 192
pBox = Me.Controls.Find(PictureBox&&index) ' Try to find pic box by ID
If Not pBox Is Nothing Then ' If able to find element by this ID
DirectCast(pBox, PictureBox).Image = bg(map(x,y))
End If
x=x+1
if x=16 then
x=0
y=y+1
End If
Next

Changing the layout order of vb.net controls

I dynamically add picture boxes to a vb.net form. However, when I add the new picture box, it is always under/below/behind the picture boxes that I previously created. Is it possible to change it so that the newly created picture box would always be in front of the others?
Thanks
Just add this code to the part that creates the pictureboxes
PictureBox.BringToFront()
Dim mypic As PictureBox = New PictureBox
mypic.Height = 13
mypic.Width = 13
mypic.Left = 100
mypic.Top = 100
mypic.Visible = True
mypic.SizeMode = PictureBoxSizeMode.Normal
mypic.Parent = Me
mypic.Image = Image.FromFile("Path of the Image")
Me.Controls.Add(mypic)
mypic.bringtofront()