loop button to check which was clicked - vb.net

In VB.net form, I have 20 buttons. They are named from btnLoc1 ~ btnLoc20. I do not want to code each button click event.
How to loop through each button to check which was clicked?
Do I need to implement timer tick to listen for button click event?

You can create a single event handler for all the Buttons. Select all the buttons in the designer, open the Properties window, click the Events button and then double-click the Click event. That will generate a Click event handler, just like when you double-click a Button in the designer, except this one will have multiple items in the Handles clause. You can then use the sender parameter to acces the Button that was clicked, e.g.
Private Sub Buttons_Click(sender As Object, e As EventArgs) Handles Button1.Click,
Button2.Click,
Button3.Click
Dim btn = DirectCast(sender, Button)
'Use btn here.
End Sub
The question then is, what do you want to do with that Button? If you want to do something different for each Button then you really should be creating separate event handlers. Alternatively, you might have a list of data and you want to use the item in that list that corresponds to the Button that was clicked. There are numerous ways to do that. One is to put the data in the Tag property of the Button itself and retrieve it from there. Another is to use concurrent indexes, e.g.
Dim buttons = Controls.OfType(Of Button)().ToArray()
Dim data = {"First", "Second", "Third"}
MessageBox.Show(data(buttons.IndexOf(btn)))
Obviously you need to ensure that the Button array and the data array do line up.

For being noticed if button was clicked - eventhandler is best choice.
But you can create only one eventhandler for all buttons
Private Sub Button_Click(sender As Object, e As EventArgs)
Dim button As Button = DirectCast(sender, Button)
MessageBox($"Button '{button.Name}' was clicked")
End Sub
Then in constructor
Public Sub New()
InitializeComponennts()
AddHandler Button1.Click, AddressOf Me.Button_Click
AddHandler Button2.Click, AddressOf Me.Button_Click
AddHandler Button3.Click, AddressOf Me.Button_Click
' and so on
End Sub
If you want to get information about how much each button was clicked, simply create dictionary and add click amount in one eventhandler
Private ButtonsClickAmount As New Dictionary(Of String, Integer)()
Private Sub Button_Click(sender As Object, e As EventArgs)
Dim button As Button = DirectCast(sender, Button)
If ButtonsClickAmount.ContainKey(button.Name) = True Then
ButtonsClickAmount(button.Name) += 1
Else
ButtonsClickAmount.Add(button.Name, 1)
End If
End Sub

Related

How to run the same sub for every single button on a form?

I have 81 buttons on a form (9x9 grid), each is named "X_Y" (such as "5_2" for X=5,Y=2). I want each button to run the same sub. There are no other buttons on the same form.
I could just do this: Private Sub TileClicked(sender As Object, e As EventArgs) Handles 0_0.Click, 0_1.Click, 0_2.Click, and so on (up to 8_8.Click), but if there's an easier/simpler way, then I'd rather do that.
Either some way to handle any button click, or something like a For loop to go through all 81 buttons.
Dim btn as Button = Nothing
For Each ctrl As Control in myForm.Controls
If TypeOf ctrl Is Button Then
btn = DirectCast(ctrl, Button)
AddHandler btn.Click, AddressOf Me.Button_Click
End If
Next
Refer here.

Using the same event handler for multiple buttons

I have 15 buttons created through design.
I want them to have a background picture whenever I click on any of them, for example:
If I click on button11 then its background will be "Hello.jpg"
If click button12 then its background will be become "Hello.jpg"
Is there a method to write a code instead of writing code for individual button?
The code should detect which button I clicked and then change its background.
Private Sub e_11_Click(sender As Object, e As EventArgs) Handles e_11.Click
e_11.Image = Image.FromFile("E:\battleship\Explode.gif")
End Sub
Is there a way that handles every button click?
Yes, you can bind the same method to multiple controls:
Private Sub MyButtons_Click(sender As Object, e As EventArgs) _
Handles e_1.Click, e_2.Click, e_3.Click, ...
Dim myButton = DirectCast(sender, Button)
myButton.Image = Image.FromFile("E:\battleship\Explode.gif")
End Sub

Detecting a radiobutton change

I have about 50 radiobuttons on one form and I don't want to create an if statement for each one to detect when one changes, they are not part of a group box. How would I detect if any radiobutton changed and then write the name to another variable?
Put all the radio buttons on a panel and loop through the panels radio button controls, programmatically adding the same event handler for each as described by #Steve. One way I like to handle the event is to assign each radio button an index into its tag property. Then just store any relevant data in a list of objects and access the data for that radio button by pulling out it's corresponding object from the list using its tag. Much easier than doing it by hand.
Edit: Good catch #Neolisk. Updated answer.
You could Always set the CheckedChanged event for all 50 radiobuttons to the same event handler.
This is an example done via code:
Private Sub OnChange(sender As System.Object, e As System.EventArgs)
Dim rb = CType(sender, RadioButton)
Console.WriteLine(rb.Name + " " + rb.Checked.ToString)
End Sub
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
AddHandler Me.RadioButton1.CheckedChanged, AddressOf OnChange
AddHandler Me.RadioButton2.CheckedChanged, AddressOf OnChange
' and so on .....'
End Sub
I have done this via code and not using the designer to avoid the long add of Handles RadioButton1.CheckedChanged, RadioButton2.CheckedChanged .......

Handle click events from large grid of Buttons?

Okay so I have multitude buttons on a form, and I want a label to display a certain number based on which button is clicked. For example, if any of the buttons in row one of the buttons is clicked, the label would display 10. If any of the buttons from row two are clicked, the label would display 17, etc. How can I do this?
You can use the Handles keyword to handle multiple events, from multiple objects, using one Sub method, for instance:
Private Sub Row1ButtonHandler(ByRef obj As Object, ByRef ea As EventArgs) _
Handles Button1.Click, Button2.Click, Button3.Click
Label1.Text = "1"
End Sub
Private Sub Row2ButtonHandler(ByRef obj As Object, ByRef ea As EventArgs) _
Handles Button4.Click, Button5.Click, Button6.Click
Label1.Text = "17"
End Sub
As you can see, each of those handler methods will now be called any time any of the buttons in their row are clicked.
However, it may be easier to programmatically set-up the event handlers using the AddHandler and RemoveHandler functions:
For c As Int32 = 0 to 10
Dim btn As Control = Page.FindControl("Button" & c)
AddHandler btn.Click, AddressOf MyEventHandler
Next c
Note that I have used a generic Control here and have assumed that you are looking at a webpage, but you could be more specific by using, perhaps, a LinkButton control.
You can use Handles for all button and fetch button in sender value and then add your logic.
May be help you...

Dynamic button click event handler

I've 100 buttons created dynamically in a form. How can I an add event handler to them?
You can use AddHandler to add a handler for any event.
For example, this might be:
AddHandler theButton.Click, AddressOf Me.theButton_Click
Just to round out Reed's answer, you can either get the Button objects from the Form or other container and add the handler, or you could create the Button objects programmatically.
If you get the Button objects from the Form or other container, then you can iterate over the Controls collection of the Form or other container control, such as Panel or FlowLayoutPanel and so on. You can then just add the click handler with
AddHandler ctrl.Click, AddressOf Me.Button_Click (variables as in the code below),
but I prefer to check the type of the Control and cast to a Button so as I'm not adding click handlers for any other controls in the container (such as Labels). Remember that you can add handlers for any event of the Button at this point using AddHandler.
Alternatively, you can create the Button objects programmatically, as in the second block of code below.
Then, of course, you have to write the handler method, as in the third code block below.
Here is an example using Form as the container, but you're probably better off using a Panel or some other container control.
Dim btn as Button = Nothing
For Each ctrl As Control in myForm.Controls
If TypeOf ctrl Is Button Then
btn = DirectCast(ctrl, Button)
AddHandler btn.Click, AddressOf Me.Button_Click ' From answer by Reed.
End If
Next
Alternatively creating the Buttons programmatically, this time adding to a Panel container.
Dim Panel1 As new Panel()
For i As Integer = 1 to 100
btn = New Button()
' Set Button properties or call a method to do so.
Panel1.Controls.Add(btn) ' Add Button to the container.
AddHandler btn.Click, AddressOf Me.Button_Click ' Again from the answer by Reed.
Next
Then your handler will look something like this
Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
' Handle your Button clicks here
End Sub
#Debasish Sahu, your answer is an answer to another question, namely: how to know which button (or any other control) was clicked when there is a common handler for a couple of controls? So I'm giving an answer to this question how I usually do it, almost the same as yours, but note that also works without type conversion when it handles the same type of Controls:
Private Sub btn_done_clicked(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim selectedBtn As Button = sender
MsgBox("you have clicked button " & selectedBtn.Name)
End Sub
I needed a common event handler in which I can show from which button it is called without using switch case... and done like this..
Private Sub btn_done_clicked(ByVal sender As System.Object, ByVal e As System.EventArgs)
MsgBox.Show("you have clicked button " & CType(CType(sender, _
System.Windows.Forms.Button).Tag, String))
End Sub
Some code for a variation on this problem. Using the above code got me my click events as needed, but I was then stuck trying to work out which button had been clicked.
My scenario is I have a dynamic amount of tab pages. On each tab page are (all dynamically created) 2 charts, 2 DGVs and a pair of radio buttons. Each control has a unique name relative to the tab, but there could be 20 radio buttons with the same name if I had 20 tab pages. The radio buttons switch between which of the 2 graphs and DGVs you get to see. Here is the code for when one of the radio buttons gets checked (There's a nearly identical block that swaps the charts and DGVs back):
Private Sub radioFit_Components_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs)
If sender.name = "radioFit_Components" And sender.visible Then
If sender.checked Then
For Each ctrl As Control In TabControl1.SelectedTab.Controls
Select Case ctrl.Name
Case "embChartSSE_Components"
ctrl.BringToFront()
Case "embChartSSE_Fit_Curve"
ctrl.SendToBack()
Case "dgvFit_Components"
ctrl.BringToFront()
End Select
Next
End If
End If
End Sub
This code will fire for any of the tab pages and swap the charts and DGVs over on any of the tab pages. The sender.visible check is to stop the code firing when the form is being created.