Adding PictureBoxes to Windows Form - vb.net

I've been trying to create a code to simulate a queue for something(haven't got to that yet) for school and am trying to create multiple picture boxes and store them in a list. For some reason they are not appearing...anyone got any suggestions?
Public Class Form1
Dim peoples As New List(Of PictureBox)()
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Timer1.Enabled = True
Timer1.Interval = randomnumber(100, 500)
End Sub
Sub loopover()
Timer1.Interval = randomnumber(100, 500)
End Sub
Function randomnumber(lower As Integer, upper As Integer)
Randomize()
Return Int((upper * Rnd()) + lower)
End Function
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
loopover()
newqueuemember()
End Sub
Private Sub newqueuemember()
Dim pictureBox As New PictureBox
pictureBox.Width = 50
pictureBox.Visible = True
pictureBox.Height = 50
Dim selectperson As Integer = randomnumber(1, 3)
If selectperson = 1 Then
pictureBox.Image = My.Resources.person1
ElseIf selectperson = 2 Then
pictureBox.Image = My.Resources.person2
Else
pictureBox.Image = My.Resources.person3
End If
pictureBox.Location = New Point(10, 20)
peoples.Add(pictureBox)
End Sub
End Class

Under:
peoples.Add(pictureBox)
add:
Me.Controls.Add(pictureBox)
Here's a C# reference (easily translated to VB):
https://support.microsoft.com/en-us/help/319266/how-to-programmatically-add-controls-to-windows-forms-at-run-time-by-u

Use a flow layout panel, Define the size (width, height) of the objects, then simply add them to the flow layout panel, you can even have a scrollbar if the length of the list of picture boxes is longer than the height of the panel.
FlowLayoutPanel1.controls.add(picturebox_object)

Related

collision between two picturesbox in Visual basic 2019

I'm trying to create a simple game where my character has deal with a maze, in visual basic 2019
I cannot stop my character(picturebox) from passing through a wall(picturebox).
I have to say that I am far away from an expert and it's just an important project for school.
I tried this
Dim colliding As Boolean = False
For Each PictureBox In Me.Controls
If PictureBox1.Bounds.IntersectsWith(PictureBox.Bounds) Then
colliding = True
Else
colliding = False
End If
Next
and this
Dim colliding As Boolean = False
For Each PictureBox In Me.Controls
If PictureBox IsNot PictureBox1 AndAlso PictureBox21.Bounds.IntersectsWith(PictureBox.Bounds) Then
colliding = True
Else
colliding = False
End If
Next
in both attends I failed hard, and my character (picturebox1) can still pass through a wall
Code assumes that all PictureBoxes are DIRECTLY contained by the Form itself (they are not inside another container like a Panel), and that anything besides PictureBox1 is a wall:
Dim colliding As Boolean = False
For Each PB As PictureBox In Me.Controls.OfType(Of PictureBox)
If PB IsNot PictureBox1 Then
If PB.Bounds.IntersectsWith(PictureBox1.Bounds) Then
colliding = True
Exit For
End If
End If
Next
An alternate approach using a bit of LINQ:
Public Class Form1
Private Walls As New List(Of PictureBox)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Walls = Me.Controls.OfType(Of PictureBox).Where(Function(pb) pb IsNot PictureBox1).ToList
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim colliding As Boolean = Walls.Any(Function(pb) pb.Bounds.IntersectsWith(PictureBox1.Bounds))
End Sub
End Class
Here is another option for dealing with the collision.
This assumes 4 buttons to move the 'character'
Private Enum MoveDirection
Left
Down
Right
Up
End Enum
Private Sub RightButton_Click(sender As Object, e As EventArgs) Handles RightButton.Click
MovePicBox(CharacterPicBox, MoveDirection.Right)
End Sub
Private Sub LeftButton_Click(sender As Object, e As EventArgs) Handles LeftButton.Click
MovePicBox(CharacterPicBox, MoveDirection.Left)
End Sub
Private Sub UpButton_Click(sender As Object, e As EventArgs) Handles UpButton.Click
MovePicBox(CharacterPicBox, MoveDirection.Up)
End Sub
Private Sub DownButton_Click(sender As Object, e As EventArgs) Handles DownButton.Click
MovePicBox(CharacterPicBox, MoveDirection.Down)
End Sub
Private Sub MovePicBox(PicBox As PictureBox, movement As MoveDirection)
'save the old location to move the pic box back if a clash occurs
Dim oldLocation As Point = PicBox.Location
Dim newLocation As Point
Dim stepSize As Integer = 50
'calculate new position
Select Case movement
Case MoveDirection.Down
newLocation.X = oldLocation.X
newLocation.Y = oldLocation.Y + stepSize
Case MoveDirection.Left
newLocation.X = oldLocation.X - stepSize
newLocation.Y = oldLocation.Y
Case MoveDirection.Up
newLocation.X = oldLocation.X
newLocation.Y = oldLocation.Y - stepSize
Case MoveDirection.Right
newLocation.X = oldLocation.X + stepSize
newLocation.Y = oldLocation.Y
End Select
'move the picture box
PicBox.Location = newLocation
'check if it has collided
For Each wallPicBox As PictureBox In Me.Controls.OfType(Of PictureBox)
If wallPicBox Is PicBox Then
Continue For
End If
If PicBox.Bounds.IntersectsWith(wallPicBox.Bounds) Then
'move it back
PicBox.Location = oldLocation
End If
Next
End Sub

How to make a button click quickly switch between two images in a picturebox vb

Making a joke VB program that requires a button click to make a PictureBox very quickly switch between two pictures. I tried using the sleep command but nothing changes on screen. Here's what I've tried so far.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TransClass2.Image = My.Resources._21
System.Threading.Thread.Sleep(100)
TransClass2.Image = My.Resources._11
System.Threading.Thread.Sleep(100)
End Sub
TransClass2 is a class that inherits PictureBox. It's used to add transparent functionalities to PictureBoxes.
Public Class TransClass
Inherits PictureBox
Protected Overrides Sub OnPaintBackground(e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaintBackground(e)
If Parent IsNot Nothing Then
Dim index As Integer = Parent.Controls.GetChildIndex(Me)
For i As Integer = Parent.Controls.Count - 1 To index + 1 Step -1
Dim c As Control = Parent.Controls(i)
If c.Bounds.IntersectsWith(Bounds) AndAlso c.Visible = True Then
Dim bmp As New Bitmap(c.Width, c.Height, e.Graphics)
c.DrawToBitmap(bmp, c.ClientRectangle)
e.Graphics.TranslateTransform(c.Left - Left, c.Top - Top)
e.Graphics.DrawImageUnscaled(bmp, Point.Empty)
e.Graphics.TranslateTransform(Left - c.Left, Top - c.Top)
bmp.Dispose()
End If
Next
End If
End Sub
End Class
Mark the click handler as Async, then use Await Task.Delay():
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TransClass2.Image = My.Resources._21
Await Task.Delay(100)
TransClass2.Image = My.Resources._11
Await Task.Delay(100)
End Sub
I think 100 might be too fast!

Remove Or Delete the Rectangle drawn on the PictureBox

I am currently solving a bug that will remove the created rectangle on the PictureBox. The problem is that when I click an Item on the PictureBox and Resize the windows form, the rectangle does not move on with the item selected. This is the code creating the rectangle:
Private Sub paintRectangle(pictBox As System.Windows.Forms.PictureBox, pic As Image)
If pic Is Nothing Then Exit Sub
pictBox.Image = pic
If m_rect_x = -1 And m_rect_y = -1 Then
Return
End If
Dim graphic As System.Drawing.Graphics
Dim redselpen As System.Drawing.Pen
Dim yNegative As Integer = 3
redselpen = New System.Drawing.Pen(Color.Blue)
redselpen.DashStyle = Drawing2D.DashStyle.DashDot
If pictBox.Image IsNot Nothing Then
graphic = System.Drawing.Graphics.FromImage(pictBox.Image)
graphic.DrawRectangle(redselpen, m_rect_x, m_rect_y - yNegative, SystemConfig.iRectWidth, SystemConfig.iRectHeight + 2)
pictBox.Image = pictBox.Image
End If
End Sub
After Resizing the Form, I want to remove the create a rectangle on the PictureBox.
I tried this solution but the Rectangle is still in the PictureBox.
How to remove all the drawn rectangles on the picture box? (Not on the image)
But it does not work, the rectangle is still in the picturebox.
Here's a simple example showing the Paint() event of a PictureBox being used to draw a rectangle that can be moved and turned on/off:
Public Class Form1
Private yNegative As Integer = 3
Private pt As New Nullable(Of Point)
Private drawRectangle As Boolean = False
Private Sub PictureBox1_Paint(sender As Object, e As PaintEventArgs) Handles PictureBox1.Paint
If drawRectangle AndAlso pt.HasValue Then
Using redselpen As New System.Drawing.Pen(Color.Blue)
redselpen.DashStyle = Drawing2D.DashStyle.DashDot
e.Graphics.DrawRectangle(redselpen, pt.Value.X, pt.Value.Y - yNegative, SystemConfig.iRectWidth, SystemConfig.iRectHeight + 2)
End Using
End If
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
pt = New Point(25, 25)
drawRectangle = True
PictureBox1.Invalidate()
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
drawRectangle = Not drawRectangle ' toggle the rectangle on/off
PictureBox1.Invalidate()
End Sub
Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
pt = New Point(150, 25)
drawRectangle = True
PictureBox1.Invalidate()
End Sub
End Class

How can get the correct Handler of an object?

I am making an application that requires generating panels dynamically, and in turn that each panel generated two events, one with left click and another with right mouse click.
The right click is the one that gives me trouble since I have not been able to call a Handler that I have put temporarily in the event of the left click, but now that I see that it works, I want to pass it to the ToolStripMenuItem event, but when it enters event, the sender takes ownership of the ToolStripMenuItem and in this case you would need the property "System.Windows.Forms.Panel" in order to work on the Panel object.
I am not sure if I am doing it correctly, can you support me with any idea how to do it?
Annex the code of what I have developed so far
Public Class Form1
Dim pb, pbdoors As New Panel
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim pos As Int32 = 20
Dim contador As Int16 = 1
For i As Int16 = 1 To 3
Dim pb As New Panel With
{
.Width = 120,
.Height = 460,
.Top = 10,
.Left = 10,
.Name = "Panel" & contador,
.Location = New Point(pos, 20)
}
AddHandler pb.Click, AddressOf myClickHandler_b
Me.Panel1.Controls.Add(pb)
pb.BringToFront()
pos = pos + 120
contador = contador + 1
Next
End Sub
End Class
Public Sub myClickHandler_b(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim pos As Integer = Val(TextBox38.Text)
Dim clickedLabel As Panel = DirectCast(sender, Panel)
clickedLabel.Location = New Point((clickedLabel.Location.X + 120), clickedLabel.Location.Y)
TextBox38.Text = pos
End Sub
Private Sub ToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem1.Click
myClickHandler_b(sender, e)
End Sub
In order to recognize which mouse button is clicked you should use MouseClick as event handler.
The piece of code starting with and working on that is: “AddHandler pb.MouseClick……….”
I hope this might help you:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim pos As Int32 = 20
Dim contador As Int16 = 1
For i As Int16 = 1 To 3
Dim pb As New Panel With
{
.Width = 120,
.Height = 460,
.Top = 10,
.Left = 10,
.Name = "Panel" & contador,
.Location = New Point(pos, 20)
}
AddHandler pb.MouseClick, Sub(senderO As Object, eObj As MouseEventArgs)
If eObj.Button = MouseButtons.Left Then
'Do your tasks here
MsgBox("Left button clicked")
ElseIf eObj.Button = MouseButtons.Right Then
'Do your tasks here
MsgBox("Right button clicked")
End If
End Sub
Me.Panel1.Controls.Add(pb)
pb.BringToFront()
pos = pos + 120
contador = contador + 1
Next
End Sub
Winforms only provides a single event (Click) for both mouse buttons. You need to check (and cast, given that signature) the event arguments to know when you have a right click:
Public Sub myClickHandler_b(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim mouseevent As MouseEventArgs = TryCast(e, MouseEventArgs)
If mouseevent IsNot Nothing AndAlso mouseevent.Button = MouseButtons.Right Then
RightClick(TryCast(sender, Panel))
Exit Sub
End If
'Left Click
'Ugh. Val() is not your friend.
Dim pos As Integer = Val(TextBox38.Text)
Dim clickedLabel As Control = DirectCast(sender, Control)
clickedLabel.Location = New Point((clickedLabel.Location.X + 120), clickedLabel.Location.Y)
TextBox38.Text = pos
End Sub
Public Sub RightClick(source As Panel)
End Sub
Now for the second part. In the ToolStripMenuItem1_Click() method, if you have several dynamic panels on your form, how is the method supposed to know which panel it's working with? You need something in this code knows that information, and uses it for the sender argument. Additionally, given the new handling for left vs right clicks, you also need to think carefully about how that will spill over into the click handler.
So ToolStripMenuItem1_Click() should look something (but probably not exactly!) like this:
Private Sub ToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem1.Click
myClickHandler_b(pb, Nothing)
End Sub

How to create a photo slide-show in a PictureBox?

Can anyone help me out on how to put more than 1 picture in a PictureBox then show all the pictures one by one such that it looks like a small slide-show?
I am working on a project that needs me to show all my products on the form.
Assuming WinForms since you want to use a PictureBox.
Easiest way is to just hold the images in a list and use a timer to update the PictureBox:
Public Class Form1
Private images As New List(Of Image)
Private index As Integer
Public Sub New()
InitializeComponent()
images.Add(CreateImage(Color.Blue))
images.Add(CreateImage(Color.Red))
'// images.Add(Image.FromFile("c:\myimage.png")
Timer1.Interval = 1000
Timer1.Start()
End Sub
Private Sub Timer1_Tick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer1.Tick
If images.Count > 0 Then
If index >= images.Count Then
index = 0
End If
PictureBox1.Image = images(index)
index += 1
End If
End Sub
Private Function CreateImage(ByVal whichColor As Color) As Image
Dim bmp As New Bitmap(64, 64)
Using g As Graphics = Graphics.FromImage(bmp), _
br As New SolidBrush(whichColor)
g.Clear(Color.White)
g.FillEllipse(br, New Rectangle(1, 1, 61, 61))
End Using
Return bmp
End Function
End Class
The CreateImage function is just for demonstration. You would replace that with an Images.FromFile(...) function call to load your own images. Adjust the timer accordingly.