Add event handlers for runtime created controls in runtime created forms - vb.net

Im making a class that will show a form with some text and a OK button. But I can't seem to find how to handle clicking the OK button. Here is the code that im having problems with:
Private Sub ok_click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles myForm.okButton.Click
'code
End Sub
Runtime form is called myForm
Runtime button is called okButton
How I can fix this?

You'd use AddHandler:
' ... run-time control is created ...
Dim btn As New Button
btn.Text = "Hello World!"
AddHandler btn.Click, AddressOf ok_click
In your existing handler, you do NOT use the "Handles" keyword on the end. If you need a reference to the button, use the "sender" parameter:
Private Sub ok_click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim btn As Button = DirectCast(sender, Button)
' ... do something with "btn" ...
btn.Enabled = False
End Sub

Related

Hiding Dynamically Created Buttons on click in Visual Basic Forms

Im currently trying to make dynamically created buttons disappear when clicked.
I have a Private Sub that handles when the button is clicked and increases the players score. However, i do not know how to make the specific object disappear as all the Objects are called the same name as they are created by the same subroutine set on a timer ( a new button made every 2 seconds).
I have tried adding every new button created to an array but am still struggling to make the program figure out which button has been clicked.
Any help would be greatly appreciated.
One of the parameters on your button click event handler should be sender As Object, which is a reference to the button that was clicked. You just need to cast it to a button object, the set the Visible property to false. Here is an example:
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim b As Button = CType(sender, Button)
b.Visible = False
End Sub
Further to #Icemanind's answer, you can actually do it in one line:
CType(sender, Button).Visible = False
This works without validation because you know that sender is of type Button.
If you have multiple buttons to handle, you can also add additional events to the handler so you don't end up with a zillion individual handlers:
Protected Sub Button_Click(s As Object, e As EventArgs) _
Handles _
Button1.Click, Button2.Click, Button3.Click
CType(s, Button).Visible = False
End Sub
Yet another option is to add the same handler to multiple buttons rather than adding buttons to the handler:
In Form instantiation (Sub New()):
AddHandler Button1.Click, AddressOf Button_Click
AddHandler Button2.Click, AddressOf Button_Click
AddHandler Button3.Click, AddressOf Button_Click
In Form class code:
Protected Sub Button_Click(s As Object, e As EventArgs)
CType(s, Button).Visible = False
End Sub
This last method works well with dynamic controls because you can add the handlers on the fly:
Dim button As Button
For i As Integer = 0 To 9
button = New Button With {.Name = $"Button{i}", .Text = $"Button{i}", .Left = 42, .Top = 50 + (i * 30)}
Me.Controls.Add(button)
AddHandler button.Click, AddressOf Button_Click
Next i

Get text of self object in vb.net

Let's say I have a button with the text 'A'.
When I click this button, I want a messagebox to appear with the text of what name of the button that was clicked.
I tried setting it to MessageBox.Show(Me.Text) but that just gives me the form name.
How can I refer to the text of button I just clicked?
If you have to handle multiple button click try following method
Private Sub btn_a_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
Handles btn_a.Click _
,btn_b.Click 'you can add other buttons click event here(ex. btn_c,btn_d etc)
Dim objButton As Button = DirectCast(sender, Button)
MessageBox.Show(objButton.Text)
End Sub
DirectCast() vs. CType()
The reason why MessageBox.Show(Me.Text) didn't work is that Me refers the class containing the code, in this case, the Form).
If your button's event handler only handles one button, you can just hard code the buttons name like this:
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
MessageBox.Show(Button1.Text)
End Sub
If the event handler can handle more than one button, you can use the sender argument to reference the button being clicked:
Private Sub Button_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.Click
Dim but as Button = CType(sender, Button)
MessageBox.Show(but.Text)
End Sub

Can't make click event of button created in code

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Panel1.Controls.Clear()
Dim patiekalai = New Button()
Panel1.Controls.Add(patiekalai)
patiekalai.Location = New Point(0, 0)
patiekalai.Size = New Size(80, 50)
patiekalai.Image = Image.FromFile("../M/Karštieji patiekalai.jpg")
Private Sub Patiekalai_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Patiekalai.Click
I get error while trying to add a Click event handler for my dynamically created button patiekalai:
Handles clause requires a WithEvents variable defined in the containing type or one of its base types.
You can't do this because the button does not exist until Button1 is clicked, at run-time. What you want to do is add a handler as well at run-time.
Remove the "Handles" from the "Patiekalai_Click" method. Then, after you create your control at run-time: "patiekalai.Image = Image...." add this line
AddHandler patiekalai.Click AddressOf Patiekalai_Click
This tells the click event of the button to call the selected method.

.Net WindowsForms MouseDown event not firing

As a new user to VB, I am struggling to see why this code works in one project but not in another. This code works fine if I create a new project and 2 new forms but when I place in my project, it doesn't fire at all on either left or right click.
I have tried a try/catch statement, but no errors are being reported. How do I go about troubleshooting this to find out the error. I have tried to rem out code and run after each comment but still the same. I have even tried removing all other code on the form leaving just the 2 subs but no joy. Any help would be greatly appreciated.
frmMain
Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'StorageDataSet1.Customers' table. You can move, or remove it, as needed.
Me.CustomersTableAdapter.Fill(Me.StorageDataSet1.Customers)
'TODO: This line of code loads data into the 'StorageDataSet.User' table. You can move, or remove it, as needed.
Me.UserTableAdapter.Fill(Me.StorageDataSet.User)
'Dim frmDepartmentsLive As New frmDepartment
'frmDepartmentsLive.Owner = Me
'frmDepartmentsLive.ShowDialog()
lblDate.Text = Now
Timer1.Start()
rdoCustomer.Enabled = False
rdoCustomer.Checked = True
rdoDepartment.Enabled = False
rdoDepartment.Checked = False
For Each ctrl In Me.Controls
If TypeOf ctrl Is Button Then
AddHandler CType(ctrl, Button).MouseDown, AddressOf btn_MouseDown
End If
Next
End Sub
Private Sub btn_MouseDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.MouseEventArgs)
If (e.Button = MouseButtons.Right) Then
Dim btn = CType(sender, Button)
frmRacks.buttonName = btn.Name.Replace("btn", "")
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
Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
Me.Close()
End Sub
End Class
Since the controls are on a panel, they are members of that panel's controls array, not the form's. This -- and other things -- are apparent if you look thru the form's designer (on solution explorer, click Show All, then open formXXX.designer.vb). DOnt change anything, but it shows how controls are created and added. So...
For Each ctrl In thepanelName.Controls
If TypeOf ctrl Is Button Then
AddHandler CType(ctrl, Button).MouseDown, AddressOf btn_MouseDown
End If
Next
If it is ONLY those buttons on the panel you can short cut it:
For Each btn As Button In thepanelName.Controls
AddHandler CType(ctrl, Button).MouseDown, AddressOf btn_MouseDown
Next

assigning object to button.tag

I created a Sub I want to run everytime one of two buttons is clicked. I added the handles of both buttons to the sub so that clicking either one will fire the subroutine.
I placed listview object A in buttonA.tag, and listview object B in buttonB.
When the button is clicked I do my best to extract the listview instance tucked into the button's tag. The problem is there is no instance in the tag. It is simply "nothing."
Private Sub Execute(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnA.Click, btnB.Click
Dim buttonSender As Button = Nothing
buttonSender = CType(sender, Button)
Dim btnListView As ListView = buttonSender.Tag
End Sub
-------------------Edit-1
Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.btnA.Tag = Me.lvA
Me.btnB.Tag = Me.lvB
End Sub
Your time is appreciated.
Try this,
Dim buttonSender As Button = CType(sender, Button)