How to use dynamically added toolstripmenuitem - vb.net

I'm trying to make a tool strip item that contains bookmarks and each bookmark should go to the page. How do make each button work?.
For Each b In New System.IO.DirectoryInfo("Bookmarks").GetFiles
BookmarksToolStripMenuItem.DropDownItems.Add(b.Name)
Next

You should first create a too ToolStripMenuItem, then add handlers and put it to your toolstripmenu object instead of adding to toolstripmenu a string object.
For Each b In New System.IO.DirectoryInfo("Bookmarks").GetFiles
Dim menuItem As New ToolStripMenuItem(b.Name)
'Add any handlers here
'Click handler to your menuItem.
AddHandler menuItem.Click, AddressOf menuItem_Click 'CLICK EVENT HANDLER ALSO UNIQUE
'Add menuItem to ToolStripMenu
BookmarksToolStripMenuItem.DropDownItems.Add(menuItem)
Next
Private Sub menuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
'CODE TO HANDLE CLICK EVENT
End Sub
If you don't know how to dynamicaly add handlers then take a look at examples.

Related

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

SpreadSheetGear Right Click Menu Edit in Vb.Net

Can I: Edit the right click menu of selected cells of Sheet in SpreatSheetGear to add an option like Merge, and then handle the event of selection of that menu item click?
Thanks in Advance for sharing some idea.
You ought to just be able add a new ToolStripItem to WorkbookView.ContextMenuStrip (the ContextMenuStrip property is inherited from the Control class):
' Create and add new item to WorkbookView's context menu
Dim newItem As ToolStripItem = workbookView.ContextMenuStrip.Items.Add("Merge Cells")
' Add event handler
AddHandler newItem.Click, AddressOf MenuItemMergeCells_Click
...
Private Sub MenuItemMergeCells_Click(ByVal sender As Object, ByVal e As EventArgs)
Dim item As ToolStripItem = CType(sender, ToolStripItem)
If item.Text = "Merge Cells" Then
workbookView.GetLock()
Try
' Merging is only valid for multi-cell ranges
If workbookView.RangeSelection.CellCount >= 2 Then
workbookView.RangeSelection.Merge()
End If
Finally
workbookView.ReleaseLock()
End Try
End If
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 .......

dynamically adding event handlers to dynamic panels in vb.net

Ok so i've been struggling to get my head around this for a few fays not and need some help.
so i have a series of panels that are generated
example:
For i as integer 1 to dt.rows.count
dim subpan as new panel
*Code for creating panel"
Next
the problem is i need to be able to add event handlers to each of them including, click, mouseEnter and mouseLeave but i can't figure out how to index each panel so that they can be accessed and identified. i tried using a property but that didn't seem to work or i was doing it wrong.
thanks in advance for the help.
You want the AddHandler function:
For i as integer 1 to dt.rows.count
dim subpan as new panel
subpan.ID = "subpan1" ' REQUIRED AND MUST BE UNIQUE
AddHandler subpan.Click, AddressOf subpan1_Click ' CLICK EVENT HANDLER ALSO UNIQUE
' ETC.
Next
Private Sub subpan1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
' CODE TO HANDLE CLICK EVENT
End Sub
I should mention that you can route all click events to the same event handler, they don't have to be unique unless each panel requires custom logic.
You can use AddHandler to add the handler:
For i As Integer = 1 To dt.Rows.Count
Dim subpan As New Panel()
'Code for creating panel
'Attach events:
AddHandler subpan.Click, AddressOf Some_Listener
'etc.
Next
You can then access the current Panel in the event handlers by casting the sender argument to Panel.

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.