VB.NET reference control in programmatically created sender form - vb.net

I am trying to reference a a combobox_projecttype in the sender user form. It's a programmatically created form to which I add handle
'Declare variables
Dim NewForm_SmartHUB_Projects As New Form_SmartHUB_Projects
With NewForm_SmartHUB_Projects
.Name = "Form_SmartHUB_" & sender.text & "_" & iNewForm_SmartHUB_Projects
.Text = sender.text
AddHandler NewForm_SmartHUB_Projects.Activated, AddressOf DynamicForm_NewForm_SmartHUB_ProjectsActivated
iNewForm_SmartHUB_Projects +=1
End With
and then the sub looks like this
Sub DynamicForm_NewForm_SmartHUB_ProjectsActivated(ByVal sender As Object, ByVal e As EventArgs)
Debug.Print(sender.Name)
strProjectTypeFolderName = sender.combobox_projecttype.selecteditem
End Sub
Debug.Print does return the correct name of the sender form however it seems that it doesn't see combobox_projecttype in the sender object.
iNewForm_SmartHUB_Projects is a Long that I just + 1 each next time to make different names for each userform.
What am I doing wrong and how do I reference control in programmatically created sender form?

strProjectTypeFolderName = CType(DirectCast(sender, Form).Controls.Find("combobox_projecttype_Name", True)(0), ComboBox).SelectedItem
where 'combobox_projecttype_Name' is yout combobox Name.
You can't access Form controls directly from sender (or I don't know how).
detailed steps :
Dim Frm As Form = DirectCast(sender, Form)
Dim Ctrl As Control = Frm.Controls.Find("combobox_projecttype_Name", True)(0)
Dim CB As ComboBox = CType(Ctrl, ComboBox)
strProjectTypeFolderName = CB.SelectedItem

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

Get value of multiple created controls at runtime VB.NET

I can get the value of a single control that has been created at run time, that control is a DateTimePicker, but i can't get the values of multiple controls. how do i do it?
code:
This is where i add the DateTimePicker with every click at run time.
Private Sub btnAddTime_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddTime.Click
Dim Time As New DateTimePicker()
Dim count As Integer = GroupBox1.Controls.OfType(Of DateTimePicker)().ToList().Count
Time.Location = New Point(9, (23 * count) + 22)
Time.Size = New Size(150, 20)
Time.Format = DateTimePickerFormat.Time
Time.ShowUpDown = True
Time.Name = "DateTimePicker" & (count + 1)
GroupBox1.Controls.Add(Time)
End Sub
And this is where i get the values of the controls.
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
Dim i As Integer = 0
For Each cntrl In Form3.GroupBox1.Controls
Dim dt As DateTimePicker = Form3.GroupBox1.Controls.Item("DateTimePicker" & (i + 1))
If DateTime.Now.ToString = dt.Value Then
MsgBox("P")
End If
Next
End Sub
I can only get the the value of a created control if only i specified it in the code, i think i can't get the right Name of the control. I'm trying to make the program to read every value of the control in another form while the Timer ticks. help?
Try this:
For Each cntrl In Form3.GroupBox1.Controls
If TypeOf cntrl Is DateTimePicker Then
If DateTime.Now.ToString = cntrl.Value Then
MsgBox("P")
End If
End If
Next

vb.net get contextmenustrip applicable to multiple pictureboxes

In my form I have several pictureboxes and one contextmenustrip, the contextmenustrip is supposed to use at all these pictureboxes.
A tool in the contextmenustrip is to open and view the a pdf file.
The current code is:
Private Sub ViewToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ViewToolStripMenuItem.Click
Process.Start("C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe", "C:\vb_test\" + picDrawing(1))
End Sub
I have no idea how the tool can determine which picturebox is focused and open different files.
I am using vb.net.
It seems that ContextMenu.SourceControl returns always Nothing in particular situations. I verified this problem on VS2010 when I put my ToolStripMenuItem inside a ToolStripDropDownMenu. So the answer posted by #Justin Ryan couldn't working.
A workaround could be manually set a variable when opening ContextMenu with its SourceControl.
Public Class Form1
Dim ctrlSourceControl As Control
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
AddHandler Me.ContextMenuStrip1.Opening, AddressOf setSourceControl
End Sub
Private Sub setSourceControl(sender As Object, e As System.ComponentModel.CancelEventArgs)
Me.ctrlSourceControl = CType(sender, ContextMenuStrip).SourceControl
End Sub
Private Sub Item1ToolStripMenuItem_Click(sender As System.Object, e As System.EventArgs) Handles Item1ToolStripMenuItem.Click
MsgBox(Me.ctrlSourceControl.Name)
End Sub
End Class
From this question, Tim Lentine shows how to use the SourceControl property Of a ContextMenuStrip to determine the control which opened the context menu:
Private Sub mnuWebCopy_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles mnuWebCopy.Click
Dim myItem As ToolStripMenuItem = CType(sender, ToolStripMenuItem)
Dim cms As ContextMenuStrip = CType(myItem.Owner, ContextMenuStrip)
MessageBox.Show(cms.SourceControl.Name)
End Sub
This answer is likely the same as tezzo's. Just used to this
scenario a lot, and wanted to share some security checks among many
others that may help.
Assuming
ONLY PictureBoxes can show your ContextMenu named MyContextMenu :
and you have a ToolStripMenuItem named ViewToolStripMenuItem
Declarations :
Option Strict On
Option Explicit On
Option Infer Off
Imports System.IO
' File.Exist()
Imports System.Diagnostics
' Process.Start()
Public Class Form1
Private p_SelectedPictureB As PictureBox
Private p_AcroRedPath As String = "C:\Program Files (x86)\Adobe\Reader 11.0\Reader\AcroRd32.exe"
Private p_ImageFolderPath As String = "C:\vb_test\"
Private p_TargetFileName As String = ""
' ...
End Class
Handle the Opening Event of your MyContextMenu [ContextMenu]
either by a Handles MyContextMenu.Opening hook
or AddHandler MyContextMenu.Opening, AddressOf MyContextMenu_Opening
Private Sub MyContextMenu_Opening( _
sender As Object, e As System.ComponentModel.CancelEventArgs) _
Handles MyContextMenu.Opening ' Requires Private WithEvents MyContextMenu
'Try
p_SelectedPictureB = DirectCast(MyContextMenu.SourceControl, PictureBox)
If p_SelectedPictureB.Image IsNot Nothing Then
ViewToolStripMenuItem.Enabled = True
Select Case True
Case p_SelectedPictureB Is PictureBox1:
p_TargetFileName = picDrawing(1)
ViewToolStripMenuItem.Text = "Open [" + p_TargetFileName + "]"
Case p_SelectedPictureB Is PictureBox2:
p_TargetFileName = picDrawing(2)
ViewToolStripMenuItem.Text = "Open [" + p_TargetFileName + "]"
' ...
Case Else
ViewToolStripMenuItem.Enabled = False
ViewToolStripMenuItem.Text = "Open [<Wrong PBox>]"
p_TargetFileName = ""
'e.Cancel = True
End Select
Else
ViewToolStripMenuItem.Enabled = False
ViewToolStripMenuItem.Text = "Open [<No Image>]"
p_TargetFileName = ""
'e.Cancel = True
End If
'Catch CurrentException As Exception
' MessageBox.Show(CurrentException.Message)
' ViewToolStripMenuItem.Enabled = False
' p_TargetFileName = ""
' e.Cancel = True
'End Try
' ^^ remove commenting if you're unsure.
End Sub
Prefer the use of top declared variables.
If you write plain file/folder paths inside a method or function, you could loose track of it quickly, and some time later, you don't understand why your application suddenly started to crash (because the file went deleted/application uninstalled, or the folder renamed)
=> Put path to File/Folder in a global variable
However, the best move is to retrieve that path at Runtime, and ensure the existence of the File/Folder before going further...
Private Sub ViewToolStripMenuItem_Click( _
sender As Object, e As EventArgs) _
Handles ViewToolStripMenuItem.Click
Dim TargetFile As String = p_ImageFolderPath + p_TargetFileName
If File.Exists(TargetFile) Then
' (p_AcroRedPath existence checked when application starts)
Process.Start(p_AcroRedPath, TargetFile)
Else
MessageBox.Show("The File [" + TargetFile + "] doesn't exist.")
End If
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.