I have a code that creates 30 buttons at run time on a form which works excellently
For i = 0 To 30
btn = New Button
Dim old As Padding = btn.Margin
Dim old2 As Padding = btn.Padding
btn.Tag = "X1"
btn.Name = "Drane"
btn.Text = "The power of trying"
btn.Width = 95
btn.Height = 120
btn.Margin = New Padding(10, 10, 10, 10)
btn.Padding = New Padding(0, 4, 0, 2)
btn.TextAlign = ContentAlignment.BottomCenter
btn.ImageAlign = ContentAlignment.TopCenter
btn.Font = New Font("Lucida Sans Unicode", 11)
btn.ForeColor = Color.Black
btn.BackColor = Color.White
Next i
Now I'm trying to add an extra control to hold the ids for buttons that I created at run time
btn.id = i
which would hold the ids of each particular button so I can get the value in other functions in my application. I know I have to add this somehow as a control but I just don't know how.
Please any help will be greatly appreciated in resolving this
This will extend the Button class and add an ID property.
Public Class ButtonMod
Inherits Button
Public Property ID As Integer
End Class
Then you just create them in a loop as you were doing already:
For i As Integer = 1 To 30
Dim btn As New ButtonMod
Dim old As Padding = btn.Margin
Dim old2 As Padding = btn.Padding
btn.Tag = "X1"
btn.Name = "Drane"
btn.Text = "The power of trying"
btn.Width = 95
btn.Height = 120
btn.Margin = New Padding(10, 10, 10, 10)
btn.Padding = New Padding(0, 4, 0, 2)
btn.TextAlign = ContentAlignment.BottomCenter
btn.ImageAlign = ContentAlignment.TopCenter
btn.Font = New Font("Lucida Sans Unicode", 11)
btn.ForeColor = Color.Black
btn.BackColor = Color.White
btn.ID = i
Next
Related
With this code I dynamicly add a panel with two panels inside (a header and a data panel). Within the Data panel there is also a label that I like to access.
Now I like to access the label inside the data panel but can't reach it with:
test_label.text = "this a second test"
Here the dynamicaly added panels
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim newPanelMain As Panel = New Panel With {
.Location = New Point(200, 500),
.Name = "test",
.Size = New Size(500, 500)
}
Dim newPanelHeader As Panel = New Panel With {
.Name = newPanelMain.Name & "_header",
.BackColor = Color.Orange,
.Dock = DockStyle.Top,
.Height = 50
}
newPanelMain.Controls.Add(newPanelHeader)
Dim newPanelData As Panel = New Panel With {
.Name = newPanelMain.Name & "_data",
.Dock = DockStyle.Fill,
.BorderStyle = BorderStyle.FixedSingle
}
newPanelMain.Controls.Add(newPanelData)
Dim newPanelSize As Panel = New Panel With {
.Name = newPanelMain.Name & (("_size")),
.BackColor = Color.Red,
.Height = 20,
.Width = 20,
.Location = New Point(newPanelData.Width - 20, newPanelData.Height - 20)
}
newPanelData.Controls.Add(newPanelSize)
Dim newLabel As Label = New Label With {
.Text = "This is a test",
.Name = newPanelMain.Name & (("_label")),
.Location = New Point(0, 0),
.AutoSize = True
}
newPanelData.Controls.Add(newLabel)
Me.Controls.Add(newPanelMain)
End Sub
Declare newLabel as a member variable:
Private newLabel As Label
So you can use this code:
Me.newLabel = New Label With {
.Text = "This is a test",
.Name = newPanelMain.Name & (("_label")),
.Location = New Point(0, newPanelHeader.Height + 10),
.AutoSize = True
}
newPanelData.Controls.Add(Me.newLabel)
And then change its .Text property using:
Me.newLabel.Text = "this a second test"
In a different situation (e.g. if you have multiple Labels created at runtime) remember that you can use Control.ControlCollection class:
CType(CType(Me.Controls("test"), Panel).Controls("test_data"), Panel).Controls("test_label").Text = "this is a third test"
I have three panel type objects (A, B, and C), which have been dynamically generated within another panel type control.
My question is, how can I exchange panel B to the position of panel A and panel A to the position of panel B? This will be triggered by a click on a ToolStripMenuItem.
What I had thought, was to go through the arrangement of panels to know who exists and from there to work them, is that correct?
For Each obj As Control In Panel1.Controls
MsgBox(obj.Name)
Next
This is the code that I use to move to right:
Private Sub ToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem1.Click
Dim clickedPanel = DirectCast(DirectCast(DirectCast(sender, ToolStripMenuItem).Owner, ContextMenuStrip).SourceControl, Panel)
clickedPanel.Location = New Point((clickedPanel.Location.X + 120), clickedPanel.Location.Y)
End Sub
This is the code I use to generate objects dynamically:
Private Sub TileNavItem5_ElementClick(sender As Object, e As NavElementEventArgs) Handles TileNavItem5.ElementClick
Dim pos As Int32 = cInt(TextBox38.Text)
Dim poslabel As Int16 = cInt(TextBox42.Text)
Dim posY As Int16 = 330
Dim posX As Int16 = 3
Panel1.AutoScrollPosition = New Point(0, 0)
Dim pb As New Panel With
{
.Width = 120,
.Height = 460,
.Top = 10,
.Left = 10,
.BorderStyle = BorderStyle.FixedSingle,
.BackgroundImage = Image.FromFile("C:\example.bmp"),
.BackgroundImageLayout = ImageLayout.Stretch,
.ContextMenuStrip = CntxtMnuStrpSection,
.Name = "Panel" & Val(TextBox37.Text)
}
AddHandler pb.Click, AddressOf myClickHandler_b
Dim labela As New Label With {
.AutoSize = True,
.Location = New Point((poslabel), 12),
.Text = "Section " & CInt(TextBox37.Text),
.ForeColor = Color.White,
.BackColor = Color.Transparent,
.Font = New Font(Me.Font, FontStyle.Bold),
.Name = "Label" & CInt(TextBox37.Text)
}
pb.Location = New Point(0, 0)
pb.Location = New Point(pos, 20)
Panel1.Controls.Add(pb)
pb.Controls.Add(labela)
For j = 1 To 4
Dim pbdoors As New Panel With
{
.Width = 114,
.Height = 98,
.Top = 10,
.Left = 10,
.BorderStyle = BorderStyle.FixedSingle,
.BackgroundImageLayout = ImageLayout.Stretch,
.ContextMenuStrip = CntxtMnuStrpUnit,
.Name = "Unit" & Val(TextBox37.Text) & j
}
AddHandler pbdoors.Click, AddressOf myClickHandler_doors
pbdoors.Location = New Point(posX, posY)
pb.Controls.Add(pbdoors)
posY = (posY - 100)
Next
Panel1.AutoScrollPosition = New Point(Panel1.HorizontalScroll.Maximum, Panel1.VerticalScroll.Maximum)
TextBox37.Text = CInt(TextBox37.Text) + 1
TextBox38.Text = Val(TextBox38.Text) + 120
End Sub
You just need to find the controls. Swapping is the easy part.
Finding controls is also easy if you use Control.Controls.Find(String, Boolean). But you must at least know the control's name.
The difficulty comes in here
' TextBox37.Text = CInt(TextBox37.Text) + 1 ' implicit conversion from int to string
TextBox37.Text = (CInt(TextBox37.Text) + 1).ToString()
where you must find the control by name and you have built some integer into the name. Can you keep track of how many times 1 is added to TextBox37.Text?
If you can, you can pass it into this function, and the swapping will be performed
Private Sub swap(index1 As Integer, index2 As Integer)
' build the panel names
Dim p1Name = $"Panel{index1}"
Dim p2Name = $"Panel{index2}"
' find the panels
Dim p1 = DirectCast(Panel1.Controls.Find(p1Name, True).FirstOrDefault(), Panel)
If p1 Is Nothing Then Throw New ArgumentException("index1")
Dim p2 = DirectCast(Panel1.Controls.Find(p2Name, True).FirstOrDefault(), Panel)
If p2 Is Nothing Then Throw New ArgumentException("index2")
' swap the panels
Dim temp = p2.Location
p2.Location = p1.Location
p1.Location = temp
End Sub
swap(1, 2) will swap panel 1 with 2. swap(4, 6) will swap the panel 4 with 6. This logic is not included in your question (i.e. how many times is TileNavItem5_ElementClick called?), so you know better how to incorporate it. I hope it works for you.
I have this code and I want to know how to remove all created labels in my form.
I tried to put lbl.dispose() and ltr.dispose() on a Button but it says that it's not declared or inaccessible.
Dim break As Integer = 99
For i = 0 To break
If jobA > 0 And jobA > time Then
jobA = jobA - time
Dim lbl As Label = New Label
Dim ltr As Label = New Label
lbl.Location = New System.Drawing.Point(x, 280)
lbl.Size = New System.Drawing.Point(20, 20)
lbl.Text = time + spudow(waifuu)
ltr.Location = New System.Drawing.Point(y, 250)
ltr.Size = New System.Drawing.Point(20, 20)
ltr.Text = "A"
Me.Controls.Add(lbl)
Me.Controls.Add(ltr)
ElseIf jobA > 0 And jobA < time Then
Dim lbl As Label = New Label
Dim ltr As Label = New Label
lbl.Location = New System.Drawing.Point(x, 280)
lbl.Size = New System.Drawing.Point(20, 20)
lbl.Text = jobA + spudow(waifuu)
ltr.Location = New System.Drawing.Point(y, 250)
ltr.Size = New System.Drawing.Point(20, 20)
ltr.Text = "A"
Me.Controls.Add(lbl)
Me.Controls.Add(ltr)
ElseIf jobA = time Then
Dim lbl As Label = New Label
Dim ltr As Label = New Label
lbl.Location = New System.Drawing.Point(x, 280)
lbl.Size = New System.Drawing.Point(20, 20)
lbl.Text = jobA + spudow(waifuu)
ltr.Location = New System.Drawing.Point(y, 250)
ltr.Size = New System.Drawing.Point(20, 20)
ltr.Text = "A"
Me.Controls.Add(lbl)
Me.Controls.Add(ltr)
End If
Me.Refresh()
I like Zaggler's idea of using a List(Of Label), but I'll post another approach using the .Tag property of the Labels instead. This will work well enough if all the Labels will only be added to the Form itself. If you're going to spread the Labels across multiple containers then use the List(Of Label) approach instead as it will be easier. Additionally, you can get rid of a lot of redundant code by restructuring like this (I assume there is more un-shown code that is somehow changing the "x" and "y" values!):
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim break As Integer = 99
For i = 0 To break
Dim lbl As Label = New Label
Dim ltr As Label = New Label
lbl.Tag = "dynamic"
ltr.Tag = "dynamic"
lbl.Location = New System.Drawing.Point(x, 280)
lbl.Size = New System.Drawing.Point(20, 20)
lbl.Text = ""
ltr.Location = New System.Drawing.Point(y, 250)
ltr.Size = New System.Drawing.Point(20, 20)
ltr.Text = "A"
If jobA > 0 Then
If jobA > time Then
jobA = jobA - time
lbl.Text = time + spudow(waifuu)
ElseIf jobA < TimeOfDay Then
lbl.Text = jobA + spudow(waifuu)
End If
ElseIf jobA = time Then
lbl.Text = jobA + spudow(waifuu)
End If
If lbl.Text <> "" Then
Me.Controls.Add(lbl)
Me.Controls.Add(ltr)
End If
Next i
End Sub
Then, when you want to remove the dynamic Labels, you can use code like this:
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim labels = Me.Controls.OfType(Of Label).Where(Function(x) x.Tag = "dynamic").ToList
For Each lbl As Label In labels
lbl.Dispose()
Next
End Sub
Sub RemoveAllLabels()
Dim Labels As New List(Of Label)
Dim Stack As New Stack(Of Control)
Stack.Push(Me)
While Stack.Count > 0
Dim Ctrl As Control = Stack.Pop()
Labels.Add(TryCast(Ctrl, Label))
For Each C As Control In Ctrl.Controls
Stack.Push(C)
Next
End While
For Each L As Label In Labels
If Not IsNothing(L) Then L.Dispose()
Next
End Sub
Using VB.net VS2010 and Winforms, I am simply trying to add both a picturebox and a label to a panel, but the label will not go in front of the picture box. How can I set the label as the foremost object? Using the code below, the label always ends up behind the picturebox.
Public Class MyTab
Inherits System.Windows.Forms.Panel
Public myText As New Label
Public tab_top_left as New Picturebox
Public Sub New(ByVal tab_object As tab_properties_object)
With tab_top_left
.BackgroundImage = My.Resources.tab_top_left
.Parent = Me
.Location = New Point(0, 0)
.SendToBack()
.Width = 20
.Height = 19
.Name = "tab_top_left"
End With
Dim TextString As String = tab_object.top_tab_text
myText.Font = CustomFont.GetInstance(Main.main_font_size_up3, FontStyle.Regular)
myText.ForeColor = Color.FromArgb(255, 0, 0, 0)
myText.BackColor = Color.FromArgb(255, 204, 204, 204)
myText.Text = TextString
myText.Location = New Point(0, 0)
myText.Width = 200
myText.Height = 40
myText.UseCompatibleTextRendering = True
myText.BorderStyle = BorderStyle.None
myText.Name = "tab_" & myText.Text
myText.Parent = Me
myText.BringToFront()
Me.Width = myText.Left + textSize.Width + 15
Me.Height = 40
Me.Name = "_" & TextString
Me.Location = New Point(0, 0)
End Sub
End Class
I have created a flowlayoutpanel that renders panels inside on it for navigation pruposes. Now, I am doing the add of elements programmatically do reduce slow of VB 2012 application on editing codes. But then, I have an unexpected result on adding a new panel on my flowlayoutpanel.
Here is my code on creating the new panel:
Dim AppPanel As New Panel
Dim AppTableLayoutPanel As New TableLayoutPanel
Dim RecordCountPanel As New Panel
Dim RecordCountLabel As New Label
Dim RecordNameLabel As New Label
Dim AddButton As New Button
AppPanel.Width = 259
AppPanel.Height = 43
AppPanel.Margin = New Padding(0, 0, 0, 5)
AppPanel.BackColor = SystemColors.InactiveBorder
RecordCountPanel.BackColor = Color.SteelBlue
RecordCountPanel.Margin = New Padding(0)
RecordCountPanel.Dock = DockStyle.Fill
RecordCountLabel.Anchor = System.Windows.Forms.AnchorStyles.Left
RecordCountLabel.Text = "245" '
RecordCountLabel.Width = 70
RecordCountLabel.Height = 42
RecordCountLabel.Padding = New Padding(0, 6, 0, 0)
RecordCountLabel.TextAlign = ContentAlignment.MiddleCenter
RecordCountLabel.Font = New Font("Microsoft Sans Serif", 12)
RecordCountLabel.ForeColor = Color.White
'RecordCountLabel.BackColor = Color.Orange
RecordCountLabel.Location.X.Equals(4)
RecordCountLabel.Location.Y.Equals(12)
AppTableLayoutPanel.Dock = DockStyle.Fill
AppTableLayoutPanel.ColumnCount = 3
AppTableLayoutPanel.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 33.18F))
AppTableLayoutPanel.Controls.Add(RecordCountPanel, 0, 0)
AddButton.Dock = DockStyle.Fill
AddButton.Font = New Font("Microsoft Sans Serif", 14)
AddButton.Text = "+"
RecordNameLabel.Anchor = System.Windows.Forms.AnchorStyles.Left
RecordNameLabel.Text = "Request Item Logs"
RecordNameLabel.Width = 150
RecordNameLabel.Height = 42
RecordNameLabel.Padding = New Padding(0, 6, 0, 0)
RecordNameLabel.TextAlign = ContentAlignment.MiddleLeft
RecordNameLabel.Font = New Font("Microsoft Sans Serif", 10)
AppTableLayoutPanel.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 66.82F))
AppTableLayoutPanel.Controls.Add(RecordNameLabel, 1, 0)
AppTableLayoutPanel.ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 53.0F))
AppTableLayoutPanel.Controls.Add(AddButton, 2, 0)
RecordCountPanel.Controls.Add(RecordCountLabel)
AppPanel.Controls.Add(AppTableLayoutPanel)
Main.FlowlayoutPanel.Controls.Add(AppPanel)
The text on the 2nd column is not showing
The button on the 3rd column shows unusual
In Addition:
If I remove AppTableLayoutPanel.Controls.Add(RecordCountPanel, 0, 0), the other elements will be rendered normally.