Rotate / Scroll picture boxes - vb.net

I have a row of PictureBoxes created at run time which occupy more of the form's visible width. I want them to scroll at certain intervals so the user sees all of them if he waits.
I believe I must code to a Timer.
But what is the code for that? (The Form is set scrollable, but I do not want the user to interact with it. Just click the PB he likes)
Code for PB creation
'' In Form_Load:
Dim allSeries As IEnumerable(Of String) =
Directory.EnumerateFiles(root, "*.jpg", SearchOption.AllDirectories)
For i = 0 To allSeries.Count - 1
pb(i) = New PictureBox With {
.Name = "pb" + i.ToString,
.BackColor = Color.Transparent,
.Size = New Point(250, 300),
.BorderStyle = BorderStyle.None,
.SizeMode = PictureBoxSizeMode.Zoom,
.Top = 10,
.Left = pbLeft,
.Cursor = Cursors.Hand,
.Image = Image.FromFile(allSeries(i).ToString), 'Get the Image from the Directory
.Tag = Path.GetDirectoryName(allSeries(i)) 'Store Direcyory path
}
Controls.Add(pb(i))
pbLeft = pbLeft + 300 'position next to previous
'Next
Next
Thanks!

Related

Positioning similar type objects on form programmatically in vb.net

I have a from which contains some PictureBoxes. They can be from one to many.
I create them at run-time depending on the existence of specific folders.
I create them and place them the one next to each other. This means that with a scrollable form I can view all of them easy.
My question is this: How do I position them in "rows"? For a specific form size, there can be 5 labels next to each other and infinite rows of them
How do I achieve this?
My (working) code:
Public allSeries As IEnumerable(Of String) = System.IO.Directory.EnumerateDirectories(root)
For i As Integer = 1 To allSeries.Count
Dim pb As New Windows.Forms.PictureBox With {
.Name = "pb" & i.ToString,
.Size = New Drawing.Size(500, 500),
.Location = New Point(5, 5),
.BorderStyle = BorderStyle.FixedSingle,
.SizeMode = PictureBoxSizeMode.Zoom,
.Image = Image.FromFile(allSeries(i - 1).ToString + "\sImage.jpg"),
.Tag = traveldestination, 'Store Directory path
.Cursor = Cursors.Hand}
Me.Controls.Add(pb)
For i As Integer = 2 To allSeries.Count
With Me
.Controls.Item("pb" + i.ToString).Left = .Controls.Item("pb" + (i - 1).ToString).Left + 520
End With
Next
My (bad) and (not workng) code:
Dim pbsOnForm As Integer = 13 'total PictureBoxes on Form /for this instance
Dim pbsOnRow As Integer = 5 'PictureBoxes that "fit" in a row /for this intance)
For i As Integer = 1 To pbsOnForm
If i <= pbsOnRow Then
Me.Controls.Item("pb" + i.ToString).Top = Me.Controls.Item("pb" + i.ToString).Top
End If
If i > pbsOnRow And i <= 10 Then
Me.Controls.Item("pb" + i.ToString).Top = Me.Controls.Item("pb" + (i - pbsOnRow).ToString).Top
End If
Works, but when the PcrureBoxes will be more than 10, I do not know......
While using the TableLayoutPanel would fulfill most cases for this and is probably the best way to achieve this, here is some code to align the PictureBox's in row / column.
First we want to setup a method to handle the positioning. We need some variables scoped to the Form.
Dim counter As Integer = 0
Dim xPos As Integer = 5
Dim yPos As Integer = 5
Now we use these variables in a method that sets the location.
Private Sub PositionPictureBox(pb As PictureBox, Optional imgPerRow As Integer = 5)
pb.Location = New Point(xPos, yPos)
counter += 1
If counter = imgPerRow Then
counter = 0
xPos = 5
yPos = pb.Location.Y + pb.Height + 5
Else
xPos = pb.Location.X + pb.Width + 5
End If
End Sub
Finally we call the method when the PictureBox is instantiated.
For i As Integer = 1 To allSeries.Count
Dim pb As New Windows.Forms.PictureBox
With pb
.Name = "pb" & i.ToString()
.Size = New Drawing.Size(50, 50)
.Location = New Point(5, 5)
.BorderStyle = BorderStyle.FixedSingle
.SizeMode = PictureBoxSizeMode.Zoom
.Image = Image.FromFile("...")
.Tag = allSeries(i)
.Cursor = Cursors.Hand
End With
PositionPictureBox(pb)
Me.Controls.Add(pb)
Next

Panel control stuck on visible=false

Im using vb2008 express edition.
I have a form with panel control set to visible=false( i add it for copy it properties).
I tried to add panels dynamically but when i do it, i cant see it on the form.
I even set code line for panel.visble=true but when i run the watch window it stuck on visible =false
Sub addPlayer(ByVal p As Form2.player)
' Timer1.Enabled = False
Dim gap As Integer = 20
Dim pan123 As New Panel
Dim nick As New Label, colorFrame As New Label
pan123.Size = New Size(100, 100)
pan123.BackColor = Color.AliceBlue
pan123.ForeColor = Color.Aquamarine
pan123.Location = New Point(200, 200)
'pan.Size = Panel1.Size
'pan.Location = Panel1.Location
'pan.Top = Panel1.Top + Panel1.Height * playersNum + gap * playersNum
nick.Text = p.nick
nick.Size = Label2.Size
nick.Location = Label2.Location
nick.Font = Label2.Font
nick.AutoSize = True
colorFrame.AutoSize = False
colorFrame.Size = Label3.Size
colorFrame.Location = Label3.Location
colorFrame.BackColor = p.colorP
pan123.Visible = True
'pan.Controls.Add(nick)
'pan.Controls.Add(colorFrame)
Me.Controls.Add(pan123)
'nick.Visible = True
playersNum = playersNum + 1
End Sub

Unexpected TableLayoutPanel Behavour

Hi having some issues with some nested tablelayoutpanels in a custom control
I have a tablelayoutpanel in a tablelayoutpanel in a tablelayoutpanel Crazy i know but it keeps it uniform and ordered
The custom control consists of 2 tablelayoutpanels that is placed in a table layout panel on a form and in a preview area of my main form.
Having them set at design time works fine but dynamically adding / removing the topmost ones with 1 row 2 columns into the one below it that has 1 column and x rows only Seems to break the autosizing behavior I'm chasing.
So I want the cells & rows to resize automatically based on the contents in this case labels but still remain in a neat ordered layout
There's no docking anywhere in the hierarchy of controls just anchors here and there
Here's my code to add the tablelayoutpanels below
"https://i.stack.imgur.com/vRfhE.png"
Private Sub AddControl(ByRef Counter As Counter)
Dim Gpanel As New TableLayoutPanel
Dim tlabel As New Label
Dim clabel As New Label
Dim pad As Integer = Counter.Cpad
TLPanel.AutoSizeMode = AutoSizeMode.GrowAndShrink
Gpanel.AutoSizeMode = AutoSizeMode.GrowAndShrink
Gpanel.AutoSize = True
Gpanel.GrowStyle = TableLayoutPanelGrowStyle.AddRows
Gpanel.BorderStyle = BorderStyle.FixedSingle
Gpanel.CellBorderStyle = TableLayoutPanelCellBorderStyle.Inset
TLPanel.BorderStyle = BorderStyle.FixedSingle
Gpanel.Dock = DockStyle.None
Gpanel.Padding = New Padding(0)
Gpanel.Anchor = AnchorStyles.Top Or AnchorStyles.Left
Gpanel.BackColor = Color.Transparent
Gpanel.RowCount = 1
Gpanel.ColumnCount = 2
Gpanel.RowStyles.Add(New RowStyle(SizeType.AutoSize))
Gpanel.ColumnStyles.Add(New ColumnStyle(SizeType.AutoSize))
Gpanel.ColumnStyles.Add(New ColumnStyle(SizeType.AutoSize))
tlabel.Dock = DockStyle.None
clabel.Dock = DockStyle.None
tlabel.GetPreferredSize(Size.Empty)
clabel.GetPreferredSize(Size.Empty)
tlabel.Text = Counter.Clabel
clabel.Text = Counter.Ccount.ToString
tlabel.Padding = New Padding(pad)
clabel.Padding = New Padding(pad)
tlabel.Anchor = AnchorStyles.None
clabel.Anchor = AnchorStyles.None
tlabel.ForeColor = Color.FromName(Counter.Clcolor)
clabel.ForeColor = Color.FromName(Counter.Ccolor)
Dim fontstyle As New FontStyle
fontstyle = Counter.ClfontStyle
tlabel.Font = New Font(Counter.Clfont, Counter.Clfontsize, fontstyle)
fontstyle = Counter.CcfontStyle
clabel.Font = New Font(Counter.Ccfont, Counter.Ccfontsize, fontstyle)
Gpanel.Controls.Add(tlabel, 0, 0)
Gpanel.Controls.Add(clabel, 1, 0)
TLPanel.Controls.Add(Gpanel, 0, Counter.ID)
TLPanel.RowCount += 1
TLPanel.RowStyles.Add(New RowStyle(SizeType.AutoSize))
Dim Styles As TableLayoutRowStyleCollection = TLPanel.RowStyles
Dim Cstyles As TableLayoutColumnStyleCollection = Gpanel.ColumnStyles
Gpanel.RowStyles.Item(0) = New RowStyle(SizeType.AutoSize)
TLPanel.ColumnStyles.Item(0) = New ColumnStyle(SizeType.AutoSize)
For i = 0 To Cstyles.Count - 1
Cstyles.Item(i) = New ColumnStyle(SizeType.AutoSize)
Next
For i = 0 To Styles.Count - 1
Styles.Item(i) = New RowStyle(SizeType.AutoSize)
Next
TLPanel.CellBorderStyle = TableLayoutPanelCellBorderStyle.Inset
AutoSize = True
AutoSizeMode = AutoSizeMode.GrowAndShrink
End Sub
'

Handling events of objects that were created in lists

I'm making a Scrabble game in Visual Basic. In my project, I created a list of labels that will make up my "tiles" of the game board. I'm just wondering how I would handle events for labels in the list, because they aren't objects that I created in the designer. (ex: Click, Hover events)
Here is the code that creates the grid of labels:
Dim labels As New List(Of Label)
For i = 0 To 10
For y = 0 To 10
Dim temp As New Label
With temp
Dim nfont As New Font("Fixedsys Excelsior 2.00", 15)
.Name = Str(i)
.AllowDrop = True
.BackColor = Color.White
.Location = New Point(y * 55 + 465, i * 45)
.Size = New System.Drawing.Size(50, 50)
.Visible = True
.Image = Image.FromFile("E:\Scrabble\Images\Blank.png")
.CreateControl()
.TextAlign = ContentAlignment.MiddleCenter
.ForeColor = Color.LimeGreen
.Font = nfont
End With
Me.Controls.Add(temp)
labels.Add(temp)
Next
Next
You would add the handler before adding the label in the list:
AddHandler temp.Click, AddressOf LabelClickHandler
Me.Controls.Add(temp)
labels.Add(temp)

problems adding controls to a groupbox

I am creating a grid of textboxes inside a groupbox in vb.net. they are all of a uniform width,height, font etc.. the code I currently have is this:
Dim new_cell As New TextBox
With new_cell
.Multiline = True
.Width = cell_width
.Height = cell_height
.Font = ("arial", 12)
End With
For j = 0 To N
For i = 0 To M
new_cell.Left = (i * cell_width) + i
new_cell.Top = (j * cell_width) + j
space.Controls.Add(new_cell)
Next
Next
where M,N are the grid size and space is the groupbox.
this was supposed to create the whole grid however it only creates one textbox at the bottom corner. This is because the changes to new_cell on the next iteration of the loop affect the previous control and so a new control is never added. I could replace the single textbox with an array and then loop through and add each element of the textbox array to the groupbox. this however creates ugly code and seems inefficient( what with the repeated properties for each cell) and so I was wondering whether there was a way to add a control to a groupbox and then disassociate (or something) the textbox variable and the textbox added to the groupbox.
You create only one TextBox. You need to move Dim new_cell As New TextBox inside the i loop.
For j = 0 To N
For i = 0 To M
Dim new_cell As New TextBox
With new_cell
.Multiline = True
.Width = cell_width
.Height = cell_height
.Font = ("arial", 12)
End With
new_cell.Left = (i * cell_width) + i
new_cell.Top = (j * cell_width) + j
space.Controls.Add(new_cell)
Next
Next
Or even better:
Dim cell_x As Integer = space.DisplayRectangle.Left
Dim cell_y As Integer = space.DisplayRectangle.Top
Dim cell_i As Integer = 0 ': Cell `i` spacing
Dim cell_j As Integer = 0 ': Cell `j` spacing
For j = 0 To N
For i = 0 To M
space.Controls.Add(New TextBox() With {
.Name = String.Format("N{0}M{1}", j, i),
.Multiline = True,
.Width = cell_width,
.Height = cell_height,
.Font = New Font("arial", 12),
.Left = (cell_x + (i * (cell_width + cell_i))),
.Top = (cell_y + (j * (cell_height + cell_j)))
})
Next
Next