Handling events of objects that were created in lists - vb.net

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)

Related

Generate Panels based on dynamic location

I have a big panel and a function which generates panels which hold two labels. Each panel is generated under the previous one, in a message-based system.
The function looks like this:
Function GenerateMessage(ByVal author As String, ByVal message As String)
Dim user_name As String = author
Dim user_id As String = message
Dim Lbl As New Panel
AddHandler Lbl.DoubleClick, AddressOf DoubleC
AddHandler Lbl.MouseDown, AddressOf MouseDownme
AddHandler Lbl.MouseEnter, AddressOf Hoverme
AddHandler Lbl.MouseLeave, AddressOf Leaveme
Lbl.Name = "messagePanel"
If lastSavedControl Is Nothing Then
Lbl.Location = New Point(My.Settings.LastMessageX, My.Settings.LastMessageY + 70)
Else
Lbl.Location = New Point(lastSavedControl.Location.X, lastSavedControl.Location.Y + 70)
End If
Lbl.Size = New System.Drawing.Size(containerReceived.Width, containerReceived.Height)
Lbl.Font = New Font("Leelawadee UI", 10, FontStyle.Regular)
Lbl.BorderStyle = BorderStyle.None
Lbl.Cursor = Cursors.Hand
Lbl.Visible = True
Lbl.BackColor = Color.Transparent
Lbl.ForeColor = Color.Silver
Lbl.Anchor = AnchorStyles.Left + AnchorStyles.Top
chatPanel.Controls.Add(Lbl)
Debug.WriteLine(Lbl.Location.X)
Debug.WriteLine(Lbl.Location.Y)
My.Settings.LastMessageX = Lbl.Location.X
My.Settings.LastMessageY = Lbl.Location.Y
Dim newAuthor As New Label
AddHandler newAuthor.DoubleClick, AddressOf LabelDoubleC
AddHandler newAuthor.MouseDown, AddressOf LabelMouseDown
AddHandler newAuthor.MouseEnter, AddressOf LabelHover
AddHandler newAuthor.MouseLeave, AddressOf LabelMouseLeave
newAuthor.Name = "authorLbl"
newAuthor.AutoSize = True
newAuthor.Location = New Point(messageReceived.Location.X, 6) ' 9, 5
newAuthor.Font = New Font("Leelawadee UI", 12, FontStyle.Regular)
newAuthor.Cursor = Cursors.Hand
newAuthor.Anchor = AnchorStyles.Top + AnchorStyles.Left
newAuthor.Visible = True
newAuthor.Text = $"#{user_name}"
newAuthor.Tag = "userLbl"
newAuthor.BackColor = Color.Transparent
newAuthor.ForeColor = Color.Black
Lbl.Controls.Add(newAuthor)
newAuthor.Parent = Lbl
Dim newMessage As New Label
AddHandler newMessage.DoubleClick, AddressOf LabelDoubleC
AddHandler newMessage.MouseDown, AddressOf LabelMouseDown
AddHandler newMessage.MouseEnter, AddressOf LabelHover
AddHandler newMessage.MouseLeave, AddressOf LabelMouseLeave
newMessage.Name = "messageLbl"
newMessage.Location = New Point(messageReceived.Location.X, 35) ' 9, 5
For Each lineofText In chatBox.Lines
newMessage.Size = New Point(messageReceived.Width, 12 * lineofText)
Next
newMessage.Font = New Font("Leelawadee UI", 9, FontStyle.Regular)
newMessage.Cursor = Cursors.Hand
newAuthor.Anchor = AnchorStyles.Top + AnchorStyles.Left
newMessage.Visible = True
newMessage.Text = user_id
newMessage.Tag = "idLbl"
newMessage.BackColor = Color.Transparent
newMessage.ForeColor = Color.Black
Lbl.Controls.Add(newMessage)
newMessage.Parent = Lbl
End Function
My.Settings.LastMessageX and My.Settings.LastMessageY are two integers defined which are saved on each panel generation. lastSavedControl is also a variable, defined at run-time, which holds the entire control. But using the Y location from lastSavedControl doesn't seem to make a difference.
I also have AutoScroll enabled on the big panel to help with scrolling when there are too many messages to fit.
When the scrollbar is enabled and scrolled all the way down, the Y (height) property on the generated panel seems to skip. It doubles every time I generate a new panel. I suspect it's because the Y value of the big panel changes when the scrollbar is used. I don't know how to get around this.
Example image of panels skipping
I have unsuccessfully tried to save the location of the previously generated panel, and the bug seems to bypass that, likely because of the Y value of the big panel changing when scrolling.

Rotate / Scroll picture boxes

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!

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
'

Make and change TableLayoutPanel at runtime in WinForms

I would like to know how to make and change a TableLayoutPanel at runtime in VB.NET, WinForms.
I've had a look at the MSDN documentation but I can't seem to understand how to vary the number of columns/rows (ie create new ones) nor how to change the values of any of the cells.
My aim is to have a 4x4 grid that contains 16 labels, whose text comes from a multi-dimensional (4x4) integer array.
My current code is:
Dim table As New TableLayoutPanel
table.ColumnCount = 4
table.RowCount = 4
table.RowStyles.Add(New RowStyle(SizeType.Absolute, 8.0F))
This is based off the MSDN examples, but I'm not sure how to use the RowStyles.Add(several arguments) method. Can anyone explain it?
The following will create a TableLayoutPanel and all labels at run time. It is fully adjustable, in that you have have a 2 dimensional array of any size and it will display all values within that array. Using this code example should show you how to add rows and columns to a TableLayoutPanel dynamically at runtime.
Public Class Form1
Friend WithEvents TableLayout As TableLayoutPanel
Private DataArray(,) As Integer = New Integer(3, 3) {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15, 16}}
Public Sub New()
' This call is required by the designer.
InitializeComponent()
' Add any initialization after the InitializeComponent() call.
Me.AutoSizeMode = Windows.Forms.AutoSizeMode.GrowAndShrink
Me.AutoSize = True
TableLayout = New TableLayoutPanel
With TableLayout
.Name = "tableLayout"
.Margin = New System.Windows.Forms.Padding(0, 0, 0, 0)
.ColumnCount = 0
.RowCount = 0
.Dock = DockStyle.Fill
.AutoSizeMode = Windows.Forms.AutoSizeMode.GrowAndShrink
.AutoSize = True
End With
Me.Controls.Add(TableLayout)
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
For x = LBound(DataArray, 1) To UBound(DataArray, 1)
Me.TableLayout.ColumnCount += 1
Me.TableLayout.ColumnStyles.Add(New ColumnStyle(SizeType.AutoSize))
For y = LBound(DataArray, 2) To UBound(DataArray, 2)
If y = LBound(DataArray, 2) Then
Me.TableLayout.RowCount += 1
Me.TableLayout.RowStyles.Add(New ColumnStyle(SizeType.AutoSize))
End If
Dim lbl = New Label
With lbl
.Name = "lbl" & x & y
.TextAlign = ContentAlignment.MiddleCenter
.Text = "Value: " & DataArray.GetValue(x, y)
.Dock = DockStyle.Fill
.AutoSize = True
End With
Me.TableLayout.Controls.Add(lbl, y, x)
Next
Next
End Sub
End Class
I suggest to you to create a TableLayoutPanel using Designer and after that to check the auto generated code in Designer.cs (Designer.vb in your case) class. Here small example in C#:
// tableLayoutPanel1
//
this.tableLayoutPanel1.ColumnCount = 4;
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.Location = new System.Drawing.Point(252, 75);
this.tableLayoutPanel1.Name = "tableLayoutPanel1";
this.tableLayoutPanel1.RowCount = 4;
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute, 20F));
this.tableLayoutPanel1.Size = new System.Drawing.Size(200, 100);
this.tableLayoutPanel1.TabIndex = 4;
To add Controls to your TableLayout use it Controls property. For example:
private void button2_Click(object sender, EventArgs e)
{
Label label = new Label();
label.Text = "Hello!";
tableLayoutPanel1.Controls.Add(label, 0, 0);
}
enter code here