VB.NET get control name from button created at run time - vb.net

I have this code to create 3 buttons at run time, which seems to be working ok.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim rawData As String
Dim FILE_NAME As String = "C:\temp\test.txt"
Dim data() As String
Dim objReader As New System.IO.StreamReader(FILE_NAME)
Do While objReader.Peek() <> -1
rawData = objReader.ReadLine() ' & vbNewLine
data = Split(rawData, ",")
'data 0 = X loc, data 1 = Y loc, data 2 = Part Num, data 3 = Reference Des
Dim dynamicButton As New Button
dynamicButton.Location = New Point(data(0), data(1))
dynamicButton.Height = 20
dynamicButton.Width = 20
dynamicButton.FlatStyle = FlatStyle.Flat
dynamicButton.BackColor = Color.Transparent
dynamicButton.ForeColor = Color.FromArgb(10, Color.Transparent)
'dynamicButton.Text = "+"
dynamicButton.Name = data(2)
dynamicButton.FlatAppearance.BorderColor = Color.White
'dynamicButton.Font = New Font("Georgia", 6)
AddHandler dynamicButton.Click, AddressOf DynamicButton_Click
Controls.Add(dynamicButton)
Dim myToolTipText = data(3)
ToolTip1.SetToolTip(dynamicButton, myToolTipText)
Loop
End Sub
I want to get the control name that was created when I click a button, but I cannot seem to get what I need. I have been doing this on the dynamicButton_click event.
Private Sub DynamicButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
For Each cntrl In Me.Controls
If TypeOf cntrl Is Button Then
MsgBox("")
Exit Sub
End If
Next
End Sub

All you need to do is cast the sender variable to button. It will tell you which control was the source of the event:
Private Sub DynamicButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim btn As Button = DirectCast(sender, Button)
MessageBox.Show("You clicked: " & btn.Name)
End Sub

You attached an event handler to the dynamic button and that is hitting?
Couple ways you can do this:
This will give you the button you just clicked without needing to loop, the sender is the button. You need to cast it from the object to button:
MessageBox.Show(DirectCast(sender, Button).Name)
Otherwise, inside your loop, cast cntrl (the generic Control object) to the specific Button control object and then get the name.
Dim btn as Button = DirectCast(cntrl, Button)
MessageBox.Show(btn.Name)

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 :)

How to create widget name from a string in VB.NET?

I am working on a music program that gives user the option to enter a number in a textbox and creates that many buttons inside a container. I want every button created to be named 'btn' followed by a number generated in a loop. Following is the code I have so far:
Private Sub txtNum_TextChanged(sender As Object, e As EventArgs) Handles txtNum.TextChanged
For i As Integer = 1 To CInt(txtNum)
Dim strName as String = "btn" & i.ToString()
Dim <strName> as New Button
Next
End Sub
I know the line in my code where the button is being created doesn't work. How can I do this? Is there another way I can achieve this in VB.NET?
You should set the Name property of a button with, but I think you should avoid using the TextChanged event to do this. This handler is called everytime you type a single character in the textbox (also when your user mistypes something and the cancel its input to fix the error) so it is better to have a Create button that on click event handles the task
Private Sub bntCreate_Click(sender As Object, e As EventArgs) Handles btnCreate.Click
For i As Integer = 1 To CInt(txtNum.Text)
Dim strName as String = "btn" & i.ToString()
Dim btn as New Button
btn.Name = strName
' Now calculate the Location property to place your button
btn.Location = new Point(0, i * 20)
' Set the button click handler (same handler for all buttons)
AddHandler btn.Click, AddressOf onClick
' And finally add it to the form controls collection.
Me.Controls.Add(btn)
Next
End Sub
Sub onClick(ByVal sender as Object, ByVal args as EventArgs)
Dim btn = DirectCast(sender, Button)
if btn.Name = "btn1" Then
' Code for btn1
else if btn.Name = "btn2" Then
.....
End If
End Sub
The tricky part is how to position the buttons on your form. In the sample above the buttons are places in a vertical arrangement with 20 pixels of interval between their Top location, but this leads to other problems (buttons can be placed outside the form borders). If the number of buttons allows is high then you should try to use a FlowLayoutPanel to have them automatically arranged according to the FlowLayout settings
you have to add the button to the controls of your form, and create an event handler
> Private Sub txtNum_TextChanged(sender As Object, e As EventArgs)
> Handles txtNum.TextChanged
> For i As Integer = 1 To CInt(txtNum)
> Dim strName as String = "btn" & i.ToString()
> Dim btn as New button
> With btn
> .Size = (100,20)
> .Location = (20,20)
> End With
> AddHandler btn.Clicked, AddressOf btn_Clicked
> MyForm.Controls.Add(btn )
> Next
> End Sub

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.

Add a Link Button on Each Click Event in VB

I have a drop down list with a bunch of product names in it with an add button on the side. Everytime I press the add button, I want a Linkbutton to appear with the name of the product. I did the pnl.Controls.Add(New LinkButton), but it only adds one and then goes away next time I go to click. Here is the code I have right now that is making a LinkButton appear at click, just can't figure out how to alter the logic to add a new one each time.
Private Sub btnAddLinkedProjects_Click(sender As Object, e As EventArgs) Handles btnAddLinkedProjects.Click
lbLinkedProject.Visible = True
lbLinkedProject.Text = ddlParentProject.SelectedItem.Text
End Sub
I have a linkbutton in my designer that is set to invisible until it's clicked. Ultimately, when the link button of the project is clicked on, it fills in all of the fields like this
Private Sub lbLinkedProject_Click(sender As Object, e As EventArgs) Handles lbLinkedProject.Click
Dim intParentRecID As Integer
Dim pid As Project = Nothing
Dim intCityState As Integer = 0
Dim strState As String = ""
Dim cs As nsCityState = Nothing
intParentRecID = Integer.Parse(ddlParentProject.SelectedValue)
pid = oDesignCon.getProjectByRecID(intParentRecID)
If pid Is Nothing Then
Else
intCityState = pid.CityState
cs = New nsCityState(intCityState)
If cs Is Nothing Then
Else
strState = cs.StateShort
Me.ddlAddState.SelectedValue = strState
Call HandleAddStateChanged()
End If
Call nsLinqFormBinder.LoadContainer(Me.pnlCreateNewPID, pid)
Me.ddlAddAssignTo.SelectedIndex = 0
End If
End Sub
What's wrong if you just create new LinkButton as usual :
Private Sub btnAddLinkedProjects_Click(sender As Object, e As EventArgs) Handles btnAddLinkedProjects.Click
'create & prepare new LinkButton'
Dim newLinkedProject As New LinkButton
newLinkedProject.Visible = True
newLinkedProject.Text = ddlParentProject.SelectedItem.Text
'register event handler'
AddHandler newLinkedProject.Click, AddressOf Me.lbLinkedProject_Click
'add the LinkButton to panel'
pnl.Controls.Add(newLinkedProject)
End Sub

VB 2013 How to Convert Working Code to Dynamic

Hello I have a working code for a project i am making...
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim FolderDlg = FolderBrowserDialog1
'Checks if there is a value to the Selected folder
If FolderDlg.SelectedPath = "" Then
'If no value asks to set one
MsgBox("Please Set a Directory")
FolderDlg.ShowDialog()
If DialogResult.OK Then
Button1.Text = Path.GetFileName(FolderDlg.SelectedPath)
End If
Exit Sub
End If
Process.Start("explorer.exe", FolderDlg.SelectedPath)
End Sub
I want to be able to have "AddNew" Button that creates a a copy of this code. I know how to create dynamic buttons but they all call the same FolderBrowserDialog..
EDIT This is My Add New Button That Creates Buttons With Tags And Also Creates FolderBrowserDialogs with Tags.
Private Sub AddNew_Click(sender As Object, e As EventArgs) Handles AddNew.Click
Dim count As Integer = FloLay.Controls.OfType(Of Button)().ToList().Count
Dim button As New Button()
count = FloLay.Controls.OfType(Of Button)().ToList().Count
'button.Location = New System.Drawing.Point(150, 25 * count)
'button.Size = New System.Drawing.Size(60, 20)
button.Name = "button_" & (count + 1)
button.Text = "Button_ " & (count + 1)
button.Tag = "Button_" & (count + 1)
AddHandler button.Click, AddressOf Set_Dir
Dim FolderDlg As New FolderBrowserDialog
count = FloLay.Controls.OfType(Of FolderBrowserDialog)().ToList().Count
FolderDlg.Tag = "FolderDlg_" & (count + 1)
FloLay.Controls.Add(button)
End Sub
EDIT 3 This is My NEW NEW Event Handler
Private Sub Set_Dir(sender As Object, e As EventArgs)
Dim btn = DirectCast(sender, Button)
If btn.Tag Is Nothing Then
Using fbd As New FolderBrowserDialog
fbd.ShowDialog()
btn.Tag = fbd.SelectedPath
End Using
End If
Dim path = CStr(btn.Tag)
' MsgBox(path)
Process.Start("explorer.exe", path)
End Sub
Now only to Add the Button.Name = GetFileNAme and persistance after app restart or reboot
EDIT 4
Private Sub Set_Dir(sender As Object, e As EventArgs)
Dim btn = DirectCast(sender, Button)
If btn.Tag Is Nothing Then
Using fbd As New FolderBrowserDialog
fbd.ShowDialog()
btn.Tag = fbd.SelectedPath
btn.Text = path.GetFileName(fbd.SelectedPath)
End Using
Exit Sub
End If
Dim Folderpath = CStr(btn.Tag)
' MsgBox(Folderpath)
Process.Start("explorer.exe", Folderpath)
End Sub
Now It Works like a Charm!
You can't create a copy of the code. What you need to do is have the code in the event handler determine what to do based on the Button that was clicked. When you create a Button, you can store some data in its Tag property. In the event handler, the sender parameter is a reference to the object that raised the event, i.e. the Button that was clicked. You can then get that data back from its Tag property and use it. You would use that data to configure the FolderBrowserDialog in whatever manner is appropriate for that Button. E.g.
Creating the Button:
Dim btn As New Button
AddHandler btn.Click, AddressOf ButtonClicked
Me.Controls.Add(btn)
Inside the event handler:
Dim btn = DirectCast(sender, Button)
If btn.Tag Is Nothing Then
Using fbd As New FolderBrowserDialog
fbd.ShowDialog()
btn.Tag = fbd.SelectedPath
End Using
End If
Dim path = CStr(btn.Tag)
'Use path here.
Note that the Tag property is type Object so it can be anything you want. It can be as simple as an Integer or as complex as a DataSet. You simply cast it as the appropriate type in the event handler and then access all the data as normal.