Handle click events from large grid of Buttons? - vb.net

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

Related

Labels' Click events

I have an application where I have around 50 labels. In those labels a number is visible.
When the user clicks on the label the number needs to be written to an edit box.
This works fine, the only problem is that I have added 50 functions like below, and every time it’s the same. I was wondering if there is a common function for this
Remark: The labels have different names. So if its possible that this will work for all the labels on the form.
Private Sub LI_L_Click(sender As Object, e As EventArgs) Handles LI_L.Click
cmbOBJID.Text = LI_L.Text
End Sub
In the form designer, you should be able to set the handler for every label to the same function. Then you can use the "sender" parameter to determine which label is raising the event.
Notice also how all the controls that the function is linked to are listed after the "Handles" keyword. This is another way you could connect the code to all the labels if you prefer this over using the Visual Studio UI properties grid.
Private Sub LI_Click(sender As Object, e As EventArgs) Handles Label1.Click, Label2.Click, Label3.Click
cmdOBJID.Text = DirectCast(sender, Label).Text
End Sub
While it is easy to add several events to one handler in the style of
Private Sub LI_Click(sender As Object, e As EventArgs) Handles Label1.Click, Label2.Click, Label3.Click
It will be tedious for more than just a few labels.
You can add handlers programatically if you can find a way to refer to the labels you need to add handlers to. In this example, I put all the labels in a groupbox named "GroupBoxOptions":
Option Infer On
Option Strict On
Public Class Form1
Sub TransferDataToEditBox(sender As Object, e As EventArgs)
Dim lbl = DirectCast(sender, Label)
tbEditThis.Text = lbl.Text
End Sub
Sub InitLabelHandlers()
For Each lbl In GroupBoxOptions.Controls.OfType(Of Label)
AddHandler lbl.Click, AddressOf TransferDataToEditBox
Next
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
InitLabelHandlers()
End Sub
End Class
You may have some other way of selecting the labels which use the handler.
A pretty nice and quick solution is to traverse all the label controls on a form, assigning through the AddHandler function the event to run when a user clicks a label.
In code:
For Each c As Control In Me.Controls.OfType(Of Label)
AddHandler c.Click, AddressOf myLabelClick
Next
With the prevous snippet, we loop onto all the winform controls of type Label. A loop like that is useful when we have a lot of labels for which an event must be assigned. For each of them, we associate the event Click of the control with a customized Sub named myLabelClick. That subroutine will look like the following:
Private Sub myLabelClick(sender As Object, e As EventArgs)
cmdObjId.Text = DirectCast(sender, Label).Text
End Sub
Here we use the sender variable (which represents the control for which the click has been done) to access its Text property, and change the cmdObjId.Text accordingly.
Just to complement the solution from BlueMonkMN:
If you are using the DevExpress Tools, you need to import DevExpress.XtraEditors and change Label to LabelControl:
DirectCast(sender, LabelControl).Text
This worked for me.

loop button to check which was clicked

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

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

onClick Event For Picturebox

I have more than 30 picture box in a windows form named
PictureBox1
PictureBox2
PictureBox3
.....so on
I am having to write the same procedure for click function for every single one of them.
I just want to be able to write a single handler that would handle the click events for all the PictureBox and call the same function.
For a rough technical example.. Sorry for the JavaScript Format
picturebox.onclick(){
var a=get_index(this); //gets address of the clicked picturebox
somefunction(a);
}
If you are using the Handles keyword, which is the default, typical way to handle events from controls, you can add multiple event names to the Handles clause, for instance:
Private Sub OnClick(sender As Object, e As EventArgs) Handles PictureBox1.Click, PictureBox2.Click, PictureBox3.Click
' Handles click events from PictureBox1, PictureBox2, and PictureBox3
End Sub
Alternatively, you can declare the event handler method without the Handles clause, and then manually attach it to the events yourself, like this:
Private Sub OnClick(sender As Object, e As EventArgs)
' ...
End Sub
' ...
AddHandler PictureBox1.Click, AddressOf OnClick
AddHandler PictureBox2.Click, AddressOf OnClick
AddHandler PictureBox3.Click, AddressOf OnClick
Or, if you have list of picture box controls, you could add the event handlers in a loop, like this:
Dim myPictureBoxes() As PictureBox = {PictureBox1, PictureBox2, PictureBox3}
For Each i As PictureBox in myPictureBoxes
AddHandler i.Click, AddressOf OnClick
Next
Or, you could access them from your form's Controls collection by name:
For i As Integer = 1 to 30
Dim c As Control = Me.Controls("PictureBox" & i.ToString())
AddHandler c.Click, AddressOf OnClick
Next
Bear in mind, however, if you do manually call AddHandler, you need to also call RemoveHandler to later detach the event handler.
It seems odd, on the surface, to have so many picture boxes like that, though. You may want to consider custom-drawing your content in a single control or look into dynamically loading the controls at run-time.

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