How to programmatically add controls to a form in VB.NET - vb.net

I am working on an inventory in Visual Basic 2010 Express Edition. I don't know the number of fields that will be necessary for the inventory. My hope was that I could add textboxes/checkboxes/buttons using for loops in the program. Is there a way to add controls to a form without using the toolbox?
Can I add controls by instantiating them in the program?

Yes.
Private Sub MyForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim MyTextbox as New Textbox
With MyTextbox
.Size = New Size(100,20)
.Location = New Point(20,20)
End With
AddHandler MyTextbox.TextChanged, AddressOf MyTextbox_Changed
Me.Controls.Add(MyTextbox)
'Without a help environment for an intelli sense substitution
'the address name and the methods name
'cannot be wrote in exchange for each other.
'Until an equality operation is prior for an exchange i have to work
'on an as is base substituted.
End Sub
Friend Sub MyTextbox_Changed(sender as Object, e as EventArgs)
'Write code here.
End Sub

Dim numberOfButtons As Integer
Dim buttons() as Button
Private Sub MyForm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Redim buttons(numberOfbuttons)
for counter as integer = 0 to numberOfbuttons
With buttons(counter)
.Size = (10, 10)
.Visible = False
.Location = (55, 33 + counter*13)
.Text = "Button "+(counter+1).ToString ' or some name from an array you pass from main
'any other property
End With
'
next
End Sub
If you want to check which of the textboxes have information, or which radio button was clicked, you can iterate through a loop in an OK button.
If you want to be able to click individual array items and have them respond to events, add in the Form_load loop the following:
AddHandler buttons(counter).Clicked AddressOf All_Buttons_Clicked
then create
Private Sub All_Buttons_Clicked(ByVal sender As System.Object, ByVal e As System.EventArgs)
'some code here, can check to see which checkbox was changed, which button was clicked, by number or text
End Sub
when you call: objectYouCall.numberOfButtons = initial_value_from_main_program
response_yes_or_no_or_other = objectYouCall.ShowDialog()
For radio buttons, textboxes, same story, different ending.

Public Class Form1
Private boxes(5) As TextBox
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim newbox As TextBox
For i As Integer = 1 To 5 'Create a new textbox and set its properties26.27.
newbox = New TextBox
newbox.Size = New Drawing.Size(100, 20)
newbox.Location = New Point(10, 10 + 25 * (i - 1))
newbox.Name = "TextBox" & i
newbox.Text = newbox.Name 'Connect it to a handler, save a reference to the array & add it to the form control.
AddHandler newbox.TextChanged, AddressOf TextBox_TextChanged
boxes(i) = newbox
Me.Controls.Add(newbox)
Next
End Sub
Private Sub TextBox_TextChanged(sender As System.Object, e As System.EventArgs)
'When you modify the contents of any textbox, the name of that textbox
'and its current contents will be displayed in the title bar
Dim box As TextBox = DirectCast(sender, TextBox)
Me.Text = box.Name & ": " & box.Text
End Sub
End Class

To add controls dynamically to the form, do the following code. Here we are creating textbox controls to add dynamically.
Public Class Form1
Private m_TextBoxes() As TextBox = {}
Private Sub Button1_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) _
Handles Button1.Click
' Get the index for the new control.
Dim i As Integer = m_TextBoxes.Length
' Make room.
ReDim Preserve m_TextBoxes(i)
' Create and initialize the control.
m_TextBoxes(i) = New TextBox
With m_TextBoxes(i)
.Name = "TextBox" & i.ToString()
If m_TextBoxes.Length < 2 Then
' Position the first one.
.SetBounds(8, 8, 100, 20)
Else
' Position subsequent controls.
.Left = m_TextBoxes(i - 1).Left
.Top = m_TextBoxes(i - 1).Top + m_TextBoxes(i - _
1).Height + 4
.Size = m_TextBoxes(i - 1).Size
End If
' Save the control's index in the Tag property.
' (Or you can get this from the Name.)
.Tag = i
End With
' Give the control an event handler.
AddHandler m_TextBoxes(i).TextChanged, AddressOf TextBox_TextChanged
' Add the control to the form.
Me.Controls.Add(m_TextBoxes(i))
End Sub
'When you enter text in one of the TextBoxes, the TextBox_TextChanged event
'handler displays the control's name and its current text.
Private Sub TextBox_TextChanged(ByVal sender As _
System.Object, ByVal e As System.EventArgs)
' Display the current text.
Dim txt As TextBox = DirectCast(sender, TextBox)
Debug.WriteLine(txt.Name & ": [" & txt.Text & "]")
End Sub
End Class

You can get your Button1 location and than increase the Y value every time you click on it.
Public Class Form1
Dim BtnCoordinate As Point
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim btn As Button = New Button
BtnCoordinate.Y += Button1.Location.Y + 4
With btn
.Location = New Point(BtnCoordinate)
.Text = TextBox1.Text
.ForeColor = Color.Black
End With
Me.Controls.Add(btn)
Me.StartPosition = FormStartPosition.CenterScreen
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Button1Coordinate = Button1.Location
End Sub
End Class

Related

How can get the correct Handler of an object?

I am making an application that requires generating panels dynamically, and in turn that each panel generated two events, one with left click and another with right mouse click.
The right click is the one that gives me trouble since I have not been able to call a Handler that I have put temporarily in the event of the left click, but now that I see that it works, I want to pass it to the ToolStripMenuItem event, but when it enters event, the sender takes ownership of the ToolStripMenuItem and in this case you would need the property "System.Windows.Forms.Panel" in order to work on the Panel object.
I am not sure if I am doing it correctly, can you support me with any idea how to do it?
Annex the code of what I have developed so far
Public Class Form1
Dim pb, pbdoors As New Panel
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim pos As Int32 = 20
Dim contador As Int16 = 1
For i As Int16 = 1 To 3
Dim pb As New Panel With
{
.Width = 120,
.Height = 460,
.Top = 10,
.Left = 10,
.Name = "Panel" & contador,
.Location = New Point(pos, 20)
}
AddHandler pb.Click, AddressOf myClickHandler_b
Me.Panel1.Controls.Add(pb)
pb.BringToFront()
pos = pos + 120
contador = contador + 1
Next
End Sub
End Class
Public Sub myClickHandler_b(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim pos As Integer = Val(TextBox38.Text)
Dim clickedLabel As Panel = DirectCast(sender, Panel)
clickedLabel.Location = New Point((clickedLabel.Location.X + 120), clickedLabel.Location.Y)
TextBox38.Text = pos
End Sub
Private Sub ToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem1.Click
myClickHandler_b(sender, e)
End Sub
In order to recognize which mouse button is clicked you should use MouseClick as event handler.
The piece of code starting with and working on that is: “AddHandler pb.MouseClick……….”
I hope this might help you:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim pos As Int32 = 20
Dim contador As Int16 = 1
For i As Int16 = 1 To 3
Dim pb As New Panel With
{
.Width = 120,
.Height = 460,
.Top = 10,
.Left = 10,
.Name = "Panel" & contador,
.Location = New Point(pos, 20)
}
AddHandler pb.MouseClick, Sub(senderO As Object, eObj As MouseEventArgs)
If eObj.Button = MouseButtons.Left Then
'Do your tasks here
MsgBox("Left button clicked")
ElseIf eObj.Button = MouseButtons.Right Then
'Do your tasks here
MsgBox("Right button clicked")
End If
End Sub
Me.Panel1.Controls.Add(pb)
pb.BringToFront()
pos = pos + 120
contador = contador + 1
Next
End Sub
Winforms only provides a single event (Click) for both mouse buttons. You need to check (and cast, given that signature) the event arguments to know when you have a right click:
Public Sub myClickHandler_b(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim mouseevent As MouseEventArgs = TryCast(e, MouseEventArgs)
If mouseevent IsNot Nothing AndAlso mouseevent.Button = MouseButtons.Right Then
RightClick(TryCast(sender, Panel))
Exit Sub
End If
'Left Click
'Ugh. Val() is not your friend.
Dim pos As Integer = Val(TextBox38.Text)
Dim clickedLabel As Control = DirectCast(sender, Control)
clickedLabel.Location = New Point((clickedLabel.Location.X + 120), clickedLabel.Location.Y)
TextBox38.Text = pos
End Sub
Public Sub RightClick(source As Panel)
End Sub
Now for the second part. In the ToolStripMenuItem1_Click() method, if you have several dynamic panels on your form, how is the method supposed to know which panel it's working with? You need something in this code knows that information, and uses it for the sender argument. Additionally, given the new handling for left vs right clicks, you also need to think carefully about how that will spill over into the click handler.
So ToolStripMenuItem1_Click() should look something (but probably not exactly!) like this:
Private Sub ToolStripMenuItem1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ToolStripMenuItem1.Click
myClickHandler_b(pb, Nothing)
End Sub

Visual Indication of Focus and Adding Click Event To all TextBoxes

I'm working on a program wherein I have around 400 Text Boxes and I need to program an effect to make them show that they have focus. I can get the visual part down (Unless someone knows how to add a soft blue outline to a text box in VB), but I'm having trouble with creating GotFocus and LostFocus events that handle all of my Text Boxes at once. I've tried
Dim txtBox = Me.Controls.OfType(Of TextBox)
Private Sub TextBox_GotFocus(sender As Object, e As EventArgs) Handles txtBox.GotFocus
But I get a "Must have WithEvents variable" error which I don't quite understand how to fix. I've tried
Public Sub txtBoxGotFocusHandler(ByVal sender As Object,
ByVal e As System.EventArgs)
For Each txtBox As TextBox In Me.Controls 'References all text boxes in form
If txtBox.Focus = True Then
txtBox.BackColor = Color.Black
End If
Next
And I've tried a few other somewhat related things I've seen around the internet, but to no avail. Any help would be appreciated
You can make your app at runtime with any controls. You could query the layout of your app from SQL and from a simple change your app layout changes.
Private FocusRectangle As System.Drawing.Graphics
Private OldRectangle As System.Drawing.Graphics
Private MyTextBoxes As New List(Of TextBox)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MyTextBoxes.Clear()
For xcount = 0 To 399
MyTextBoxes.Add(New TextBox)
With MyTextBoxes.Item(xcount)
.Name = "MyTextBoxes" & (xcount + 1).ToString
.Text = ""
.Location = New Point(0, 0)
.Size = New Size(50, 13)
.Visible = True
AddHandler .GotFocus, AddressOf MyTextBoxes_GotFocus
AddHandler .LostFocus, AddressOf MyTextBoxes_LostFocus
End With
Me.Controls.Add(MyTextBoxes.Item(xcount))
'add them to a panel....
'Panel1.Controls.add(MyTextBoxes.Item(xcount))
Next
End Sub
Sub MyTextBoxes_GotFocus(sender As Object, e As EventArgs)
Dim ThisTextBox As TextBox = DirectCast(sender, TextBox)
Dim xPen As New System.Drawing.Pen(Color.LightBlue)
FocusRectangle = Me.CreateGraphics()
FocusRectangle.DrawRectangle(xPen, ThisTextBox.Location.X - 1, ThisTextBox.Location.Y - 1, ThisTextBox.Size.Width + 1, ThisTextBox.Size.Height + 1)
OldRectangle = FocusRectangle
End Sub
Sub MyTextBoxes_LostFocus(sender As Object, e As EventArgs)
Dim ThisTextBox As TextBox = DirectCast(sender, TextBox)
OldRectangle.Dispose()
End Sub
Private Sub Form1_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
MyTextBoxes.Item(0).Focus()
End Sub
If you created your form with the Designer, the WithEvents is added for you automatically.
If you are declaring 400 text boxes as Private fields, you would declare them as Private WitheEvents txtBox As TextBox
If you're creating the text boxes programatically and adding them to a collection of textboxes or something, then you can't do WithEvents.
But all WithEvents does is allow you to add Handeles TextBox.SomeEvent to a function. Instead you can do this:
Dim txtBox As New TextBox
...
AddHandler txtBox.GotFocus, AddressOf txtBoxGotFocusHandler
Me.Controls.Add(txtBox)

loop through list box in vb and get a total amount

I’m trying to loop through a list of prices on a list box and print the total in a textbox on the form. The loop I have works, but the figures it produces are all wrong!. can any one help me??
the figures look ok but then when i add more items to the list box the total amount goes all wrong.
Public Class f
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'LoftDataSet.Services' table. You can move, or remove it, as needed.
Me.ServicesTableAdapter.Fill(Me.LoftDataSet.Services)
'Loop through all the rows that are in the dataset
For Each dr As DataRow In LoftDataSet.Services.Rows
Dim btn As New Button 'Instantiate a button
btn.Text = dr("service_name").ToString 'UserName is a field in my Users Table
btn.Size = New Size(140, 80)
btn.Tag = dr("ID") 'Here we set the tag to the primary key (ID)
'Since we're using a flowlayoutpanel, we don't need to worry about setting the location property
FlowLayoutPanel1.Controls.Add(btn) 'Add the button to the flow layout panel
AddHandler btn.Click, AddressOf UserClick 'Here we give the button a handler for the click event
Next
End Sub
Public Class Product
Public Property ProductName As String
Public Property ProductCost As Decimal
Public Overrides Function ToString() As String
Return ProductCost & " " & ProductName
'Here you could build a formatted string to the user to include cost
End Function
End Class
'Here we write our method for the click event of the button(s) we created
Dim SelectedProduct As New Product
Private Sub UserClick(ByVal sender As Object, ByVal e As EventArgs)
'We set a filter to the binding source passing it ID=<and whatever is stored in the tag property>
ServicesBindingSource.Filter = "ID = " & DirectCast(sender, Button).Tag.ToString
SelectedProduct.ProductName = DirectCast(sender, Button).Text
SelectedProduct.ProductCost = DirectCast(ServicesBindingSource(0), DataRowView).DataView(0)(2)
ListBox1.Items.Add(SelectedProduct)
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
For i As Integer = ListBox1.SelectedIndices.Count - 1 To 0 Step -1
ListBox1.Items.RemoveAt(ListBox1.SelectedIndices(i))
Next
End Sub
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim aValue As Decimal
For Each item As Product In ListBox1.Items
aValue += CDec(item.ProductCost)
Next
TextBox1.Text = aValue
End Sub
End Class
Cycle through each item using an integer as your count.
For i As Integer = 0 To ListBox1.Items.Count - 1
MsgBox(ListBox1.Items(i).ToString)
Next
Or you can add it to an integer/double value
For i As Integer = 0 To ListBox1.Items.Count - 1
MyInteger += Double.Parse.ListBox1.Items(i).ToString)
Next
MsgBox(MyInteger)
'Now the messagebox will show your total
EDIT:
Do not use ListBo1.Items.Item(i). Access directly through Listbox1.Items(i)

vb2010 getting name values from multiple buttons

At the moment, I have a button that sends a value to another form and displays result in a label. The problem is, I have 20 buttons that are labeled a to w that need to be coded and I am stumped as to how I can pass values from multiple buttons. Would it be a case statement in the form being passed to? I am a new user to VB.Net and still finding my way so any help would be gratefully received. I have included code sample for the first button 'A'. Thanks
frmMain
Private Sub btnA_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles btnA.MouseDown
If (e.Button = MouseButtons.Right) Then
'Dim curButton As Button = DirectCast(sender, Button)
'frmRacks.buttonName = curButton.Name 'Dynamic alternative to frmRacks.buttonName = "A"
frmRacks.buttonName = "A"
frmRacks.Show()
ElseIf (e.Button = MouseButtons.Left) Then
MessageBox.Show("To be coded")
End If
End Sub
frmRacks
Public Class frmRacks
Public buttonName As String
Private Sub racksfrm_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblRacks.Text = buttonName
End Sub
EDIT: New project
Public Class Form1
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim button1 As Button = New Button
Dim button2 As Button = New Button
Dim button3 As Button = New Button
With button1
.Name = "button1"
.Left = 0
AddHandler .MouseDown, AddressOf btn_MouseDown
'Add remaining properties for button1
End With
With button2
.Name = "button2"
.Left = 100
AddHandler .MouseDown, AddressOf btn_MouseDown
'Add remaining properties for button2
End With
With button3
.Name = "button3"
.Left = 200
AddHandler .MouseDown, AddressOf btn_MouseDown
'Add remaining properties for button3
End With
Me.Controls.Add(button1)
Me.Controls.Add(button2)
Me.Controls.Add(button3)
End Sub
Private Sub btn_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Dim curButton As Button = DirectCast(sender, Button)
Dim curButtonName As String = curButton.Name 'This string would change on account of the button you have clicked
Form2.buttonName = curButtonName
Form2.Show()
'MessageBox.Show("You clicked the button called " & curButtonName.ToUpper)
End Sub
End Class
Public Class Form2
Public buttonName As String
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
lblRacks.Text = buttonName
End Sub
End Class
Here you have a sample code which hopefully will help you to get clearer ideas:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim button1 As Button = New Button
Dim button2 As Button = New Button
Dim button3 As Button = New Button
With button1
.Name = "button1"
.Left = 0
AddHandler .MouseDown, AddressOf btn_MouseDown
'Add remaining properties for button1
End With
With button2
.Name = "button2"
.Left = 100
AddHandler .MouseDown, AddressOf btn_MouseDown
'Add remaining properties for button2
End With
With button3
.Name = "button3"
.Left = 200
AddHandler .MouseDown, AddressOf btn_MouseDown
'Add remaining properties for button3
End With
Me.Controls.Add(button1)
Me.Controls.Add(button2)
Me.Controls.Add(button3)
End Sub
Private Sub btn_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
Dim curButton As Button = DirectCast(sender, Button)
Dim curButtonName As String = curButton.Name 'This string would change on account of the button you have clicked
MessageBox.Show("You clicked the button called " & curButtonName.ToUpper)
End Sub

How to program a button made in code

For example, if on form load Button1 was created, how would I make this button function?
Public WithEvents newButton As Windows.Forms.Button
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim i As Integer
For i = 1 To 5
newButton = New Windows.Forms.Button
newButton.Name = "btnButton" & i
newButton.Text = "Button " & i
newButton.Top = 20 + i * 30
newButton.Left = 40
AddHandler newButton.Click, AddressOf ButtonClicked
Me.Controls.Add(newButton)
Next
End Sub
Private Sub ButtonClicked(ByVal sender As Object, ByVal e As EventArgs)
MsgBox("You clicked: " & sender.name &amp; vbCrLf & "Button name: " & sender.Text)
End Sub
Reference
If you double click the button in the designer view you will be taken to the code-behind for the Button_Click event. There you can add any functionality you want to have happen when the button is clicked by the user.