Dynamic TableLayout and Control - vb.net

created dynamic table layout and add some controls in to that table layout.my code
Protected Overrides Sub OnLoad(e As EventArgs)
MyBase.OnLoad(e)
dynamicTable.ColumnCount = 5
dynamicTable.RowCount = 1
For i = 1 To 5
Dim button= New button()
button.Text = i.ToString()
dynamicTable.SetColumn(button, i)
dynamicTable.Controls.Add(button)
Next
Next
End Sub
Now i added 5 buttons to the table layout.
Now i am going to click on the button. How can i know ,on which button i clicked ?

Try like this
Dim dynamicTable As New TableLayoutPanel
dynamicTable.ColumnCount = 5
dynamicTable.RowCount = 1
For i = 1 To 5
Dim button = New Button()
button.Name = "button" & i
AddHandler button.Click, AddressOf Click1
Button.Text = i.ToString()
dynamicTable.SetColumn(button, i)
dynamicTable.Controls.Add(button)
Next
Me.Controls.Add(dynamicTable)
Private Sub Click1(ByVal sender As System.Object, ByVal e As System.EventArgs)
If sender.Name = "button1" Then
MsgBox("Hi")
End If
End Sub

Related

How to acces checked status of dynamicaly created Radio Buttons in VB

I create a variable amount of radio buttons in a Tab Page by reading the lines out of an array using:
Public Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim rbgen As RadioButton
Dim tab1 = 0
For y As Integer = 0 To Array.GetUpperBound(0) Step 1
If Array(y, 0) = "ABC" Then
rbgen = New RadioButton
rbgen.Name = "RButton" & Convert.ToString(y)
rbgen.Left = 10
rbgen.Top = ((tab1) * 30)
rbgen.Text = Array(y, 2)
rbgen.Size = New System.Drawing.Size(260, 40)
TabPage1.Controls.Add(rbgen)
tab1 = tab1 + 1
End If
Next
End Sub
When i click a "start" Button i need to run different code depending on the checked RadioButton. But how do i access the information of which radio Button is checked?
Thank you very much for your help!
You could try to add a Handler after you add the radio button:
AddHandler rbgen.CheckedChanged, AddressOf RadioBox_CheckedChanged
and then you need to add this sub
Private Sub RadioBox_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim RadioBox As RadioButton = TryCast(sender, RadioButton)
If RadioBox IsNot Nothing Then
MessageBox.Show(RadioBox.CheckState)
End If
End Sub
and if you want to check the status
For Each RadioBox In TabPage1.Controls.OfType(Of RadioButton)()
if Ctype(TabPage1.controls("RadioButton" & i), radiobutton).checked = true then
'your Code Here
end if
next
I could not test it yet but I hope I already helped you a little bit :)

Refresh a panel when some controls deleted programmaticaly

I am using this part of code to add a Label, a TextBox a Button and a RadioButton into a Panel:
Private Sub AppsAdd_Button_Click(sender As Object, e As EventArgs) Handles AppsAdd_Button.Click
Dim lbl As New Label()
Dim count As Integer = Apps_Panel.Controls.OfType(Of Label)().ToList().Count
lbl.Name = "AppLabel_" & (count + 1)
lbl.Text = "Application #" & (count + 1) & ":"
lbl.Location = New Point(0, 28 * count)
lbl.AutoSize = False
lbl.Size = New Size(114, 21)
lbl.TextAlign = ContentAlignment.MiddleRight
lbl.Tag = count + 1
Apps_Panel.Controls.Add(lbl)
Dim txtbox As New TextBox()
count = Apps_Panel.Controls.OfType(Of TextBox)().ToList().Count
txtbox.Name = "AppTextbox_" & (count + 1)
txtbox.Text = "..."
txtbox.Location = New Point(120, 28 * count)
txtbox.Size = New Size(387, 21)
txtbox.Tag = count + 1
AddHandler txtbox.TextChanged, AddressOf TextBox_Changed
Apps_Panel.Controls.Add(txtbox)
Dim btn As New Button()
count = Apps_Panel.Controls.OfType(Of Button)().ToList().Count
btn.Name = "AppBrowseButton_" & (count + 1)
btn.Text = "Browse"
btn.Location = New Point(513, 28 * count)
btn.Size = New Size(75, 21)
btn.Tag = count + 1
AddHandler btn.Click, AddressOf Button_Click
Apps_Panel.Controls.Add(btn)
Dim radiobtn As New RadioButton()
count = Apps_Panel.Controls.OfType(Of RadioButton)().ToList().Count
radiobtn.Name = "AppRadio_" & (count + 1)
radiobtn.Text = ""
radiobtn.Location = New Point(590, 28 * count)
radiobtn.Size = New Size(14, 21)
radiobtn.Tag = count + 1
AddHandler radiobtn.Click, AddressOf RadioButton_Click
Apps_Panel.Controls.Add(radiobtn)
End Sub
Private Sub TextBox_Changed(sender As Object, e As EventArgs)
Dim textbox As TextBox = TryCast(sender, TextBox)
End Sub
Private Sub Button_Click(sender As Object, e As EventArgs)
Dim button As Button = TryCast(sender, Button)
End Sub
Private Sub RadioButton_Click(sender As Object, e As EventArgs)
Dim RadioButton As RadioButton = TryCast(sender, RadioButton)
AppToDel_Label.Text = RadioButton.Tag
End Sub
Then I use this to remove selected controls:
Private Sub AppsDel_Button_Click(sender As System.Object, e As System.EventArgs) Handles AppsDel_Button.Click
Dim Ctrl As Control
For controlIndex As Integer = Apps_Panel.Controls.Count - 1 To 0 Step -1
Ctrl = Apps_Panel.Controls(controlIndex)
If Ctrl.Name Like "*" & AppToDel_Label.Text Then
RemoveHandler Ctrl.TextChanged, AddressOf TextBox_Changed
RemoveHandler Ctrl.Click, AddressOf Button_Click
RemoveHandler Ctrl.Click, AddressOf RadioButton_Click
Apps_Panel.Controls.Remove(Ctrl)
Ctrl.Dispose()
End If
Next
End Sub
When selected controls are in the bottom of panel, panel is getting smaller in height when I delete them. But if I choose to delete from the top or the middle of panel "list", leaves an empty space and panel don't shrink! Any idea? There is anyway to refresh the panel so it can fill in the empty space?
Here is a video example.
Use a FlowLayoutPanel instead. The FlowLayoutPanel layouts the controls added to it automatically. It can arrange items horizontally or vertically.
You don't specify a location when adding them, instead you work with Margins and Paddings.
I also would combine all controls of one row (Label, TextBox, Button and RadioButton) into a UserControl. This allows you to design the rows visually instead of programmatically.
Walkthrough: Arranging Controls on Windows Forms Using a FlowLayoutPanel.
Working with Windows Forms FlowLayoutPanel (C# Corner).

How do I add buttons with event handlers to a form dynamically?

Is it possible to do this dynamically? How?
Code:
Public Class Form1
Dim c(40) As Integer
Dim IMG As PictureBox
Dim lbl_n(40) As Label
Dim lbl_pr(40) As Label
Dim lbl_ref(40) As Label
Dim lbl_dim(40) As Label
Dim lbl_col(40) As Label
Dim btn_add(40) As Button
Dim btn_rmv(40) As Button
Dim tb_qt(40) As TextBox
AddHandler btn_add(0).Click, AddressOf btn_add0_Click
AddHandler btn_add(1).Click, AddressOf btn_add1_Click
[...]
AddHandler btn_add(40).Click, AddressOf btn_add40_Click
Public Sub btn_add0_Click(ByVal sender As Object, ByVal e As System.EventArgs)
c(0) = c(0) + 1
tb_qt(0).Text = c(0)
End Sub
Public Sub btn_add1_Click(ByVal sender As Object, ByVal e As System.EventArgs)
c(1) = c(1) + 1
tb_qt(1).Text = c(1)
End Sub
[...]
Public Sub btn_add40_Click(ByVal sender As Object, ByVal e As System.EventArgs)
c(40) = c(40) + 1
tb_qt(40).Text = c(40)
End Sub
These are the images with program running (they are edited):
Form1
Form2
I want to dynamically, because I could use more than 40 products! And I need to do 40 addhandlers, so that more 40 to remove!
How can I do that?
Yes, You can do that dynamically.
In this example, I put those buttons and textboxes into Panel.
There is example with comments which line is for what :
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
'dynamically adding buttons (so You don't need create every button separately)
For x = 1 To 40
Dim btn As New Button 'create new button
btn.Name = "btn_add" & x.ToString 'set ID for button (example: btn_add1, btn_add2, ... btn_add40)
btn.Text = "+" 'set button text
btn.Tag = x.ToString 'set button NO. for finding corrent textbox whos belong to this button (for example: tb_qt1 belong to buttons btn_add1 and btn_rem1)
btn.Width = 24 'this is for styling
btn.Top = (x * btn.Height) + 3 'for styling, too. Top poistion of button
btn.Left = 0 'for styling, too. Left position of button
AddHandler btn.Click, AddressOf btnAdd_Click 'creating sub called btnAdd_Click (this sub will handle all, in this case 40, buttons)
Panel1.Controls.Add(btn) 'for this example I put buttons and textboxes into panel (autoscroll set to True)
btn = New Button 'same thing just for remove button
btn.Name = "btn_rem" & x.ToString
btn.Text = "-"
btn.Tag = x.ToString
btn.Width = 24
btn.Top = (x * btn.Height) + 3
btn.Left = btn.Width + 3
AddHandler btn.Click, AddressOf btnRem_Click 'creating sub called btnRem_Click (this sub will handle all, in this case 40, buttons)
Panel1.Controls.Add(btn)
Dim txt As New TextBox 'same thing for textboxes
txt.Name = "tb_qt" & x.ToString
txt.Text = "0"
txt.Tag = x.ToString
txt.Top = (x * btn.Height) + 3
txt.Left = btn.Left + btn.Width + 3
txt.TextAlign = HorizontalAlignment.Right
Panel1.Controls.Add(txt)
Next
End Sub
Public Sub btnAdd_Click(sender As Object, e As EventArgs)
Dim btn As Button = DirectCast(sender, Button) 'detect which button clicked. You can add line: MsgBox(btn.Name) to see what happening
Dim txt As TextBox = Panel1.Controls.Find("tb_qt" & btn.Tag.ToString, True)(0) 'find textbox which belong to this button. this is why set .Tag into buttons
txt.Text = CInt(txt.Text) + 1 'just do math and change value, by adding one(1), in textbox (by this way I avoid using Your Dim c(40) As Integer)
End Sub
Public Sub btnRem_Click(sender As Object, e As EventArgs)
Dim btn As Button = DirectCast(sender, Button) 'same thing like for btnAdd_Click, but we doing subtract for one(1) value in textbox
Dim txt As TextBox = Panel1.Controls.Find("tb_qt" & btn.Tag.ToString, True)(0)
txt.Text = CInt(txt.Text) - 1
End Sub
Because I use panel like container for all those buttons and textboxes, You have to set AutoScroll=True for panel.
I hope so You will understand how it's work for start.

Run time controls needing data back on button click

Hey all i am creating some run-time label for my form:
Dim tmpLbl As New Label
Dim intX As Integer = 0
Do Until intX = 4
With tmpLbl
.Size() = New System.Drawing.Size(58, 15)
.Text = "Run-time Controls " & intX
.Location = New System.Drawing.Point(2, 20)
.Name = "test" & intX
End With
With Me.Controls
.Add(tmpLbl)
End With
intX += 1
Loop
This works just fine... but when i want to, say place a button on the form that calls one of these run-time controls like so:
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Debug.Print(tmpLbl.Name)
End Sub
Naturally this above does not work. how can i get a labels name (ex: test2) and read its text (ex: Run-time Controls 2) when i click on that button?
Got it!
Private genTmpLbl As New List(Of Label)
Public Sub makeRunTimeControls()
Dim tmpLbl As New Label
Dim intX As Integer = 0
Do Until intX = 4
With tmpLbl
.Size() = New System.Drawing.Size(58, 15)
.Text = "Run-time Controls " & intX
.Location = New System.Drawing.Point(2, 20)
.Name = "test" & intX
End With
With Me.Controls
.Add(tmpLbl)
End With
genTmpLbl.Add(tmpLbl)
intX += 1
Loop
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
For Each label In genTmpLbl
For Each control In Me.Controls
If TypeOf (control) Is Label Then
Debug.Print(control.Name)
End If
Next
Next
End Sub

Creating buttons in runtime from Database field

I have a single columns table which holds 50 records. I would like to create 50 buttons from those records. How can I do that in Vb.Net?
Any help will be appreciated.
Assuming you mean Winforms:
Use your Datasource(f.e. a DataTable) and loop its RowCollection. For example:
Private Sub BtnLoadButtons_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnLoadButtons.Click
Dim source As New DataTable("MyButtonTable")
source.Columns.Add(New DataColumn("MyButtonColumn", GetType(String)))
For i As Int32 = 1 To 50
Dim newRow As DataRow = source.NewRow
newRow("MyButtonColumn") = "Button_" & i
source.Rows.Add(newRow)
Next
'you are loading the above DataTable from SQL-Server, now iterate the rows...'
For Each row As DataRow In source.Rows
Dim btn As New Button()
btn.Name = DirectCast(row("MyButtonColumn"), String)
btn.Text = btn.Name
btn.Location = New Point(0, Me.Panel1.Controls.Count * btn.Height)
AddHandler btn.Click, AddressOf handleButton
Me.Panel1.Controls.Add(btn)
Next
End Sub
Private Sub handleButton(ByVal sender As Object, ByVal e As EventArgs)
Dim btn As Button = DirectCast(sender, Button)
'do something ...'
End Sub
If you are working in a Winforms application you can use the FlowLayoutPanel because it automatically orders the button layouts for you:
dim i as integer=1
for each record in Table
dim btn as new Button
btn.id = "btn" & i
i+=1
Panel1.Controls.add(btn)
next