How to run the same sub for every single button on a form? - vb.net

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.

Related

VB.NET Button with both MouseMove and Click/MouseClick handlers

I'm attempting to to add both a MouseMove and a Click (or MouseClick) to a button. The end user needs the ability to click the button to add an element, but also the ability to drag the button to a specific location to add an element as well. I have both functions working independently. However, when I add both Handlers, the MouseMove takes precedence, and doesn't allow the Click to happen (attempting to click shows the DragDropEffects.None effect).
Button:
Dim Button As New Button()
'Button Attributes
AddHandler Button.Click, AddressOf Button_Click
AddHandler Button.MouseMove, AddressOf Button_MouseMove
Handlers:
Private Sub Button_MouseMove(sender As Object, e As MouseEventArgs)
Button.DoDragDrop("Button", DragDropEffects.Move)
End Sub
Private Sub Button_Click(sender As Object, e As EventArgs)
'Add Element Function
End Sub
I've also tried it with the MouseClick handler, with the same results:
AddHandler Button.MouseClick, AddressOf Button_MouseClick
Private Sub Button_MouseClick(sender As Object, e As MouseEventArgs)
'Add Element Function
End Sub
1.) What is the reasoning behind the Click/MouseClick not able to fire when a MouseMove is implemented as well?
2.) What is the proper workaround to get both functions usable? Do I need to do MouseDown and MouseUp handlers, and track the distance that the mouse has moved to determine if I clicked or if I am dragging?

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

Animate Picturebox in VB

I am new to VB and just can't figure it out how to animate a button using the MouseHover Event..
I want to create a single loop for all the buttons(picturebox) in my project that will increase the button's size when the user rests the mouse on it.
Maybe something like:
For Each Form As Form In Application.OpenForms
For Each Control As Control In Form.Controls
Tks. Any help is appreciated.
Use Inherits to create a new button (or PictureBox) class for you purpose. Here is the code.
Public Class cuteButton
Inherits System.Windows.Forms.Button
Protected Overrides Sub OnMouseHover(e As EventArgs)
'
'Wite code here to change button size or whatever.
'
MyBase.OnMouseHover(e)
End Sub
End Class
A very simple way is to use a common MouseHover event to grow your buttons (which I guess is really a Picturebox with an image in it):
Private Sub CustomButton_Grow(sender As Object, e As System.EventArgs) Handles Picturebox1.MouseHover, Picturebox2.MouseHover
'Set a maximum height to grow the buttons to.
'This can also be set for width depending on your needs!
Dim maxHeight as single = 50
If sender.Height < maxHeight then
sender.Size = New Size(sender.Width+1,sender.Height+1)
End if
End Sub
Then you can reset all buttons in a snap using the MouseLeave event. If you want that part animated as well then you can to use a global shrink routine that constantly shrink all buttons but the one in MouseHover. Good luck!
This Will Work even if you have 10,000 button or picture box ....
I am Assuming that you only have 1 form and many Buttons ,,, you have to be specific on your question
This Code will work fine with Buttons, Picturebox ,text box
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each cntrl As Control In Controls ' Looping for each Button as Control
If TypeOf cntrl Is Button Then
AddHandler cntrl.MouseEnter, AddressOf cntrl_MouseEnter ' Adding the event and handler
AddHandler cntrl.MouseLeave, AddressOf cntrl_MouseLeave ' Adding the event and handler
End If
Next
End Sub
'' Assuming you wanna eNlarge everytime the mouse Hover or Enter
Private Sub cntrl_MouseEnter(sender As Object, e As EventArgs)
CType(sender, Button).Size = New Point(CType(sender, Button).Size.Width + 50, CType(sender, Button).Size.Height + 50)
End Sub
'' Here it goes back normal size
Private Sub cntrl_MouseLeave(sender As Object, e As EventArgs)
CType(sender, Button).Size = New Point(CType(sender, Button).Size.Width - 50, CType(sender, Button).Size.Height - 50)
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.

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.