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
Related
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.
I'm trying to make a userinterface that generates itself on request (button click)
Private Sub Body_new_part_add_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Body_new_part_add.Click
So when i add a Combobox as first it's no problem it generates the box & places it on the right position etc.
Dim oTypeBox As New ComboBox
oTypeBox.Name = "Body_type_" & oBodyPartsNumber
oTypeBox.Location = New System.Drawing.Point(7, 78)
Body_parts.Controls.Add(oTypeBox)
Now i want to add another control, a textbox next to the Combobox.
Dim oTypeBox As New ComboBox
oTypeBox.Name = "Body_type_" & oBodyPartsNumber
oTypeBox.Location = New System.Drawing.Point(7, 78)
Body_parts.Controls.Add(oTypeBox)
Dim oTextbox As New TextBox
oTextbox.name = "test"
oTextbox.Location = New System.Drawing.Point(50, 78)
Body_parts.Controls.Add(oTextbox)
This gives me this error.
'New' cannot be used on an interface.
What do i need to change in order to get this done? I need to add +- 10 controls on each button click event.
Try this one
Public Class Form1
Dim cLeft As Integer = 1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
AddNewTextBox()
End Sub
Public Function AddNewTextBox() As System.Windows.Forms.TextBox
Dim txt As New System.Windows.Forms.TextBox()
Me.Controls.Add(txt)
txt.Top = cLeft * 25
txt.Left = 100
txt.Text = "TextBox " & Me.cLeft.ToString
cLeft = cLeft + 1
Return txt
End Function
End Class
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
The TabLoad() function doesn't seem to be working on clicking of this dynamic button. The aim of this button click event is that it deletes text from a text file and loads the form again.
Below is the complete code. The TabLoad() function is in the NextDelbtn_Click sub at the end.
Also any suggestion regarding change of code is appreciated.
Imports System.IO
Public Class Form1
Dim str As String
Dim FILE_NAME As String = "D:\1.txt"
Dim file_exists As Boolean = File.Exists(FILE_NAME)
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
If TextBox1.Text = "" Then
MsgBox("Please enter text that you want to save", MsgBoxStyle.Information, "TOCC Error")
Else
str = TextBox1.Text
Dim fs As FileStream = Nothing
If (Not File.Exists(FILE_NAME)) Then
fs = File.Create(FILE_NAME)
Using fs
End Using
End If
If File.Exists(FILE_NAME) Then
Dim sw As StreamWriter
sw = File.AppendText(FILE_NAME)
sw.WriteLine(str)
sw.Flush()
sw.Close()
TabLoad()
TextBox1.Text = ""
End If
End If
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
TabControl1.SelectedIndex = TabControl1.TabIndex + 1
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
TabLoad()
End Sub
Private Sub Nextbtn_Click(sender As Object, e As EventArgs)
Dim s As String = DirectCast(DirectCast(sender, Button).Tag, Label).Text
Clipboard.SetText(s)
End Sub
Private Sub TabLoad()
Dim i As Integer = 1
For Each line As String In System.IO.File.ReadAllLines(FILE_NAME)
Dim NextLabel As New Label
Dim Nextbtn As New Button
Dim NextDelbtn As New Button
NextLabel.Text = line
Nextbtn.Text = "Copy"
NextDelbtn.Text = "Delete"
NextLabel.Height = 22
Nextbtn.Width = 55
Nextbtn.Height = 22
NextDelbtn.Width = 55
NextDelbtn.Height = 22
Nextbtn.BackColor = Color.WhiteSmoke
NextLabel.Tag = Nextbtn
Nextbtn.Tag = NextLabel
NextDelbtn.Tag = NextLabel
NextDelbtn.BackColor = Color.WhiteSmoke
NextLabel.BackColor = Color.Yellow
TabPage2.Controls.Add(NextLabel)
TabPage2.Controls.Add(Nextbtn)
TabPage2.Controls.Add(NextDelbtn)
NextLabel.Location = New Point(10, 10 * i + ((i - 1) * NextLabel.Height))
Nextbtn.Location = New Point(120, 10 * i + ((i - 1) * Nextbtn.Height))
NextDelbtn.Location = New Point(180, 10 * i + ((i - 1) * NextDelbtn.Height))
AddHandler Nextbtn.Click, AddressOf Me.Nextbtn_Click
AddHandler NextDelbtn.Click, AddressOf Me.NextDelbtn_Click
i += 1
Next
File.WriteAllLines(FILE_NAME,
File.ReadAllLines(FILE_NAME).Where(Function(y) y <> String.Empty))
End Sub
Private Sub NextDelbtn_Click(sender As Object, e As EventArgs)
Dim btn As Button = CType(sender, Button)
Dim s As String = (btn.Tag).Text
Dim lines() As String = IO.File.ReadAllLines(FILE_NAME)
Using sw As New IO.StreamWriter(FILE_NAME)
For Each line As String In lines
If line = s Then
line = ""
End If
sw.WriteLine(line)
Next
sw.Flush()
sw.Close()
TabLoad()
End Using
End Sub
End Class
Your problem appears to be that you're initializing new controls but you're not changing the controls on the form or even creating a new form.
I have written a WinForm project which displays a ListBox containing a list of file names. When the user clicks a submit button, the application dynamically loads and displays one PictureBox control for each file and then waits while they are processed. As PDF files are generated for each one, the matching PictureBox for that file needs to be updated to display an image.
Here's what I have so far:
Private Sub ButtonSubmit_Click(sender As System.Object, e As System.EventArgs) Handles ButtonSubmit.Click
Dim x As Integer = 790
Dim y As Integer = 91
For i As Integer = 0 To ListBox1.Items.Count - 1
Dim key As String = ListBox1.Items(i).ToString()
'adds picturebox for as many listbox items added
Dim MyPictureBox As New PictureBox()
MyPictureBox.Name = "pic" + key
MyPictureBox.Location = New Point(x, y)
MyPictureBox.Size = New Size(12, 12)
MyPictureBox.SizeMode = PictureBoxSizeMode.StretchImage
Me.Controls.Add(MyPictureBox)
MyPictureBox.Image = My.Resources.Warning1
ToolTipSpooling.SetToolTip(MyPictureBox, "Creating PDF...")
x += 0
y += 13
Next i
Call CheckPDFs()
End Sub
Public Sub CheckPDFs()
Dim ListboxTicketIDs = (From i In ListBox1.Items).ToArray()
For Each Item In ListboxTicketIDs
Dim ID = Item.ToString
Dim Watcher As New FileSystemWatcher()
Watcher.Path = "C:\Temp\"
Watcher.NotifyFilter = (NotifyFilters.Attributes)
Watcher.Filter = ID + ".pdf"
AddHandler Watcher.Changed, AddressOf OnChanged
Watcher.EnableRaisingEvents = True
Next
End Sub
Private Sub OnChanged(source As Object, e As FileSystemEventArgs)
Dim p As PictureBox = CType(Me.Controls("pic" + ListBox1.Items.ToString()), PictureBox)
p.Image = My.Resources.Ok1
End Sub
I'm having trouble changing the PictureBox to a different picture once the item(s) listed in the listbox are present, based on the FileSystemWatcher. For instance, the files are not always created in the same order as they exist in the ListBox.
EDIT
Working code below.
Public Class Form1
Private WithEvents Watcher As FileSystemWatcher
Public Sub CheckPDFs()
For i As Integer = 0 To ListBox1.Items.Count - 1
Watcher = New FileSystemWatcher()
Watcher.SynchronizingObject = Me
Watcher.Path = "C:\Temp\"
Watcher.NotifyFilter = NotifyFilters.Attributes
Watcher.Filter = "*.pdf"
Watcher.EnableRaisingEvents = True
Next
End Sub
Private Sub Watcher_Changed(ByVal sender As Object, ByVal e As FileSystemEventArgs) Handles Watcher.Changed
Dim key As String = Path.GetFileNameWithoutExtension(e.Name)
Dim p As PictureBox = CType(Me.Controls("pic" + key), PictureBox)
p.Image = My.Resources.Ok
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
ListBox1.Items.Add(TextBox1.Text)
TextBox1.Text = ""
Dim x As Integer = 5
Dim y As Integer = 5
For i As Integer = 0 To ListBox1.Items.Count - 1
Dim key As String = ListBox1.Items(i).ToString()
'adds picturebox for as many listbox items added
Dim MyPictureBox As New PictureBox()
MyPictureBox.Name = "pic" + key
MyPictureBox.Location = New Point(x, y)
MyPictureBox.Size = New Size(15, 15)
MyPictureBox.SizeMode = PictureBoxSizeMode.StretchImage
Me.Controls.Add(MyPictureBox)
MyPictureBox.Image = My.Resources.Info
x += 0
y += 18
Next i
Call CheckPDFs()
End Sub
First of all, you don't need to create multiple file watchers. You just need a single file watcher to watch for any changes to the folder. I would recommend declaring it as a private field at the top of your form using the WithEvents keyword so you don't have to worry about adding and removing event handlers.
Next, when the watcher raises the changed event, you can get the file name of the file that changed by looking at the properties of the event args object. You need to get the name of the file that changed and then use the file name as the key to finding the matching picture box control.
Public Class Form1
Private WithEvents Watcher As FileSystemWatcher
Public Sub CheckPDFs()
Watcher = New FileSystemWatcher()
Watcher.Path = "C:\Temp\"
Watcher.NotifyFilter = NotifyFilters.Attributes
Watcher.Filter = "*.pdf"
End Sub
Private Sub Watcher_Changed(ByVal sender As Object, ByVal e As FileSystemEventArgs) Handles Watcher.Changed
Dim key As String = Path.GetFileNameWithoutExtension(e.Name)
Dim p As PictureBox = CType(Me.Controls("pic" + key), PictureBox)
p.Image = My.Resources.Ok1
End Sub
End Class
However, since you say in a comment below that the file name will not be the same as the text in the listbox, but that it will merely start with that text, you could do something like this, instead:
Private Sub Watcher_Changed(ByVal sender As Object, ByVal e As FileSystemEventArgs) Handles Watcher.Changed
Dim p As PictureBox = Nothing
For Each item As Object In ListBox1.Items
If e.Name.StartsWith(item.ToString()) Then
p = CType(Me.Controls("pic" + item.ToString()), PictureBox)
Exit For
End If
Next
If p IsNot Nothing Then
p.Image = My.Resources.Ok1
End If
End Sub