Add a Link Button on Each Click Event in VB - vb.net

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

Related

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

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)

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

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.

Identify source chart/control from ContextMenuStrip Click

I have a form with numerous charts and have added a ContextMenuStrip when a chart is right clicked so the user can copy the chart image to the clipboard
Public Sub Chart_Click(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Chart1.MouseClick, _
Chart2.MouseClick, Chart3.MouseClick, Chart4.MouseClick
If e.Button = MouseButtons.Right Then
Dim cmus As ContextMenuStrip = New ContextMenuStrip
Dim cms1 As ToolStripMenuItem = New ToolStripMenuItem("Copy as Image")
cms1.Tag = 0
cmus.Items.Add(cms1)
For Each c As ToolStripMenuItem In cmus.Items
AddHandler c.Click, AddressOf Chart_cMenu_Click
Next
cmus.Show(New Point(Control.MousePosition.X, Control.MousePosition.Y))
End If
End Sub
Then I would like to identify which chart was clicked on so that I can copy that chart to the clipboard.
This seems like a simple problem to me but I cannot figure out why no matter what I do trying to identify the Owner,Parent,SourceControl of the right click menu always returns me a Nothing value.
Public Sub Chart_cMenu_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim menuItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
Dim cms As ContextMenuStrip = CType(menuItem.Owner, ContextMenuStrip)
Dim _owner As Control = CType(cms.SourceControl, Chart)
Select Case menuItem.Text
Case "Copy as Image"
Dim ms As New System.IO.MemoryStream(100)
_owner.SaveImage(ms, ChartImageFormat.Bmp)
Dim bm As Bitmap = New Bitmap(ms)
Clipboard.SetImage(bm)
End Select
End Sub
Any ideas how to identify the source chart?
Have a messy solution. Going to leave this open in case a more elegant solution can be formed.
Add a name to your new ContextMenuStrip that reflects the Sender. This can then be used in the MouseClick method to find the origin
Public Sub Chart_Click(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles Chart1.MouseClick, _
Chart2.MouseClick, Chart3.MouseClick, Chart4.MouseClick
If e.Button = MouseButtons.Right Then
Dim cmus As ContextMenuStrip = New ContextMenuStrip
'Add the name to menu
cmus.Name = sender.Name & "_CMS"
Dim cms1 As ToolStripMenuItem = New ToolStripMenuItem("Copy as Image")
cms1.Tag = 0
cmus.Items.Add(cms1)
For Each c As ToolStripMenuItem In cmus.Items
AddHandler c.Click, AddressOf Chart_cMenu_Click
Next
cmus.Show(New Point(Control.MousePosition.X, Control.MousePosition.Y))
End If
End Sub
Now find the control that corresponds to the new name
Public Sub Chart_cMenu_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim cms As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
Dim _owner As ContextMenuStrip = CType(cms.Owner, ContextMenuStrip)
'This is where you use the name attached to the ContextMenuStrip
Dim _chartname As String = Replace(_owner.Name, "_CMS", "")
Dim parentObject As Chart = Nothing
Try
parentObject = CType(Me.Controls.Find(_chartname, True)(0), Chart)
Catch ex As Exception
End Try
If Not parentObject Is Nothing Then
Select Case cms.Text
Case "Copy as Image"
Dim ms As New System.IO.MemoryStream(100)
parentObject.SaveImage(ms, ChartImageFormat.Bmp)
Dim bm As Bitmap = New Bitmap(ms)
Clipboard.SetImage(bm)
End Select
End If
End Sub
Still think there should be an easier solution than this using the likes of Parent,Owner and SourceControl
My VB is rusty, but the below code works fine for me.
Dim menu As New ContextMenuStrip()
menu.ItemClicked += New ToolStripItemClickedEventHandler(menu_ItemClicked)
menu.Items.Add("Save As Image")
chart1.ContextMenuStrip = menu
chart2.ContextMenuStrip = menu;
Private Sub menu_ItemClicked(sender As Object, e As ToolStripItemClickedEventArgs)
If e.ClickedItem.ToString() = "Save As Image" Then
Dim menu As ContextMenuStrip = TryCast(sender, ContextMenuStrip)
If menu IsNot Nothing AndAlso menu.SourceControl IsNot Nothing Then
Dim chart As Chart = TryCast(menu.SourceControl, Chart)
Dim dlg As New SaveFileDialog()
If chart IsNot Nothing AndAlso dlg.ShowDialog() = DialogResult.OK Then
chart.SaveImage(dlg.FileName, ChartImageFormat.Jpeg)
End If
End If
End If
End Sub