I'm trying to make a button that is programmatically created and when clicked it can destroy itself (and other programmatically made objects).
This is the sub that is called to create the button (alongside two other textboxes ive removed from this code)
Public Sub createProduct(i As Integer)
'Creating the button to be able to Delete the product
'i is used as a way to keep track of each row of products
Dim DeleteProduct As Button = New Button
With DeleteProduct
.Size = New Size(20, 20)
.Location = New Point(240, 50 + (i * 25))
.Text = New String("-")
.Name = "btnRemoveProduct" + i.ToString
UserButtons.Add(DeleteProduct)
End With
Me.Controls.Add(DeleteProduct)
AddHandler DeleteProduct.Click, AddressOf DeleteProductButton
End Sub
Which links the button to this code
Friend Sub DeleteProductButton(sender As Object, e As EventArgs)
End Sub
However, I can't find any way to be able to refer to the button (and the other textboxes) in the DeleteProductButton sub, and therefore can't delete them once the button is pressed.
Related
So here's what I have:
Code that makes buttons when you click the button "New Button" (Button1).
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
ActionsMade = ActionsMade + 1
Dim actionButton = New Windows.Forms.Button
ActionContainer.Controls.Add(actionButton)
actionButton.Text = "New Action " + ActionsMade.ToString
actionButton.Width = 107
actionButton.Height = 56
AddHandler actionButton.Click, AddressOf OnActionButtonClick
End Sub
When you click the buttons that were created, it shows an input box, where you type what you want to rename the button to.
Sub OnActionButtonClick()
If IsRenaming Then
Dim renameTo As String
renameTo = InputBox("Rename ActionButton To:")
Else
MessageBox.Show("Action started! Not renaming")
End If
End Sub
The only problem is, I have no way to identify between these buttons.
tl;dr:
I created buttons programmatically
I want to rename them
I don't know how to identify between these buttons and rename them individually
This is more concise and includes a referencable button name (eg Button_03):
Private Sub MakeButton_Click(sender As Object, e As EventArgs) Handles MakeButton.Click
Static ActionsMade As Integer = 0
ActionsMade += 1
ActionContainer.Controls.Add(New Button With {
.Name = $"Button_{ActionsMade:00}",
.Text = $"New Action {ActionsMade:00}",
.Size = New Size(107, 56),
.Location = New Point(100, 250 + 25 * ActionsMade)
})
AddHandler ActionContainer.Controls($"Button_{ActionsMade:00}").Click, AddressOf OnActionButtonClick
End Sub
Note that in the above code I haven't actually defined a new button per se, just New-ed it within the Controls.Add() statement, and then used the generated button name to add the event handler.
Another way would be declare the button as an independent object and then add it:
Dim actionButton As New Button With {
.Name = $"Button_{ActionsMade:00}",
.Text = $"New Action {ActionsMade:00}",
.Size = New Size(107, 56),
.Location = New Point(100, 250 + 25 * ActionsMade)
}
ActionContainer.Controls.Add(actionButton)
AddHandler actionButton.Click, AddressOf OnActionButtonClick
Other notes:
Use of a Static ActionsMade integer variable which retains its value between calls. This could also be a module-wide variable and removed from the MakeButton_Click Sub.
Use of string interpolation in assigning the button's Name and Text properties according to a formated version of the ActionsMade value.
Use of button properties Size and Location.
Automatic increment of button vertical position based on the value of ActionsMade.
Regarding your Action Button event handler, it should look like this:
Private Sub OnActionButtonClick(sender As Object, e As EventArgs)
If ActionStarted Then
MessageBox.Show("Action started! Not renaming.")
Else
CType(sender, Button).Text = InputBox("Rename ActionButton To:")
End If
End Sub
Note that I've checked for a started Action rather than a renaming in progress but that's just an illustration of an alternative approach. Note also that you don't need to know the name of the button to change its properties.
When creating a button I want to create a click event for each button. How do I create a click event for each button created dynamically? Here is my code. It works to create a single event based on the first button created.
Sub CreateDynamicButton()
Dim ButtonNumber As Integer = 1
Dim axisX As Integer = 53
Dim axisY As Integer = 13
' Create a Button object
Do Until ButtonNumber = 11
Dim dynamicButton As New Button
' Set Button properties
dynamicButton.Location = New Point(axisX, axisY)
dynamicButton.Height = 30
dynamicButton.Width = 200
' Set background and foreground
dynamicButton.BackColor = Color.Beige
dynamicButton.ForeColor = Color.Black
dynamicButton.Text = "I am Dynamic Button" & ButtonNumber
dynamicButton.Name = "DynamicButton" & ButtonNumber
dynamicButton.Font = New Font("Georgia", 10)
AddHandler dynamicButton.Click, AddressOf dynamicButton_Click
' Add Button to the Form. Placement of the Button
' will be based on the Location and Size of button
Controls.Add(dynamicButton)
axisY = axisY + 35
ButtonNumber = ButtonNumber + 1
Loop
'Add Exit Button
Dim dynamicButtonExit As New Button
' Set Button properties
dynamicButtonExit.Location = New Point(axisX, axisY)
dynamicButtonExit.Height = 30
dynamicButtonExit.Width = 200
' Set background and foreground
dynamicButtonExit.BackColor = Color.Beige
dynamicButtonExit.ForeColor = Color.Black
dynamicButtonExit.Text = "Exit"
dynamicButtonExit.Name = "Exit"
dynamicButtonExit.Font = New Font("Georgia", 10)
AddHandler dynamicButtonExit.Click, AddressOf dynamicButtonExit_Click
' Add Button to the Form. Placement of the Button
' will be based on the Location and Size of button
Controls.Add(dynamicButtonExit)
End Sub
You don't need to create multiple event to handle your dynamic buttons, dynamicButton_Click is enough to handle all click. Better give ID for each button and you only need to do is in this event, do code as below:
Dim btn As Button = DirectCast(sender, Button)
If btn.ID = "DynamicButton1" then
'Do logic here for button 1
End If
You just need to add a little logic to handle each button click in the one event handler. If you use as 'Select Case' Statement it keeps things tidy as well.
If you have a lot of code for each button's logic, it may be better to write separate subs for each button and call the appropriate sub using each 'Case' block like in the second case block
Private Sub DynamicButton_click(sender As Object, e As EventArgs)
Dim btn As Button = DirectCast(sender, Button)
Select Case btn.Name
Case "DynamicButton1"
MessageBox.Show("button1")
Case "DynamicButton2"
dynamicbutton2_Click(sender, e)
End Select
End Sub
Private Sub dynamicbutton2_Click(sender As Button, e As EventArgs)
MessageBox.Show("Button2")
'and lots of other code
End Sub
I use Visual Basic in Visual Studio 2015 and i am trying when i click on a StripMenu to appear me some TextBoxes and Buttons.
After another click in Stripmenu i want to erase them and add new one.
My problem is in Erase (delete or clear my buttons and textboxes) controls from my surface.
I try to do it use Button.Visible =True (or False) but it's not seems to be really helpful in a big amount of controls.
Private Sub ClassAToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles ClassAToolStripMenuItem.Click
Label1.Text = "Sum A class Students: "
Dim btnA As Button = New Button
btnA.Location = New Point(420, 180)
btnA.Name = "Btn1"
btnA.Text = "OK"
btnA.Visible = True
Me.Controls.Add(btnA)
AddHandler btnA.Click, AddressOf button
End Sub
Private Sub button()
'What my Button does.
End Sub
I create dynamically through this code my Button but if i want to go in another Menu option i want to erase this button to add again my new controls (such us new buttons labels etc).
Your declaration is out of scope since you declared it in the menu's click method. You would have to use the Find method to get back the reference to the control you created:
Dim btn = Me.Controls.Find("Btn1", True).FirstOrDefault()
If btn IsNot Nothing Then
btn.Dispose()
End If
If you are trying to replace the contents of a panel with a new "screen" on your menu click, you can try code like this:
While Panel1.Controls.Count > 0
Panel1.Controls(0).Dispose()
End While
Dim newControl As New UserControl1
newControl.Dock = DockStyle.Fill
Panel1.Controls.Add(newControl)
I'm using MDI container to run my bussiness application I created for my client.
Since using MDI means that when I open several forms they will still run in background all the time untill I close them manualy.
What I need is to make User Control or anything else that could preview all opened forms in Tab Form so my client can easily close all or some of opened forms without closing a form he is curently viewing.
For now I have used this code, so for now only first clicked item from menu appears as button, but not others clicked menu items.
Private Sub MenuStrip1_ItemClicked(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ToolStripItemClickedEventArgs) Handles MenuStrip1.ItemClicked
Dim Button As New Button
Me.Panel5.Controls.Add(Button)
Button.Text = e.ClickedItem.Name
Button.Width = 50
Button.Height = 25
End Sub
Now I need to write a code to add more buttons bellow, also should add a code for adding buttons only when I click on SubMenu item (The one when is clicked new Form appear).
And also, I should now add a little Close button into previewed User-Button-Control.
From your comments, I understand that your ideas regarding adding buttons at runtime are not too clear and thus I am including a small code which hopefully will help you on this front. Start a new project and put a Panel (Panel5) and a Button (AddButtons) on it, and write this code:
Dim lastButtonIndex, lastLeft, lastTop As Integer
Private Sub Button_Click(sender As System.Object, e As System.EventArgs)
Dim curButton As Button = DirectCast(sender, Button)
If (curButton.Name = "Button1") Then
'do Button1 stuff
End If
'etc.
End Sub
Private Sub addNewButton()
lastButtonIndex = lastButtonIndex + 1
lastLeft = lastLeft + 5
lastTop = lastTop + 5
Dim Button As New Button
With Button
.Name = "Button" + lastButtonIndex.ToString()
.Text = "Button" + lastButtonIndex.ToString()
.Width = 50
.Height = 25
.Left = lastLeft
.Top = lastTop
AddHandler .Click, AddressOf Button_Click
End With
Me.Panel5.Controls.Add(Button)
End Sub
Private Sub ButtonAddButtons_Click(sender As System.Object, e As System.EventArgs) Handles AddButtons.Click
addNewButton()
End Sub
This code will add a new button to the panel every time you click on AddButtons. All the buttons will have an associated Click Event (the same one for all of them): Button_Click. The way to know which button is the current one inside this method is via sender, as shown in the code (you can put as many conditions as buttons. The names are given sequentially starting from 1; but you can take any other property as reference, curButton is the given Button Control).
Bear in mind that one of the problems you have to take care of is the location of the buttons. The code above has a very simplistic X/Y values (Left/Top properties) auto-increase which, logically, will not deliver what you want.
I have come across an issue that has completely bamboozled me.
I have a dynamically added DataGridView with many columns and rows and what I am trying to achieve is on mouse_up I want a button to be drawn over the selected cells. So for example if I select the first 3 cells of row3, a button should be drawn over the 3 cells.
I have tried using the X and Y of each selected cell and convert it to a buttoncolumn but that didn't work. What I currently have is sample code that just adds button to the screen but they do not appear on the screen (thus the title). Once I get the buttons to appear on the screen I will then try to draw them over the selected cells but I need to get over this hurdle first
This is the code I am using:
'I dynamically add the DataGridView
Grid = New DataGridView
Grid.Dock = DockStyle.Fill
Grid.BackgroundColor = Color.White
Grid.RowHeadersVisible = False
Grid.AllowUserToOrderColumns = False
Grid.AllowUserToResizeRows = False
...
TabControl.SelectedTab.Controls.Add(Grid)
AddHandler Grid.CellMouseUp, AddressOf Grid_MouseUp
...
'On mouse up it calls the sub to add buttons
Private Sub Grid_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellMouseEventArgs)
Dim i As Integer
For i = 1 To 30
NewButton(i) 'calls the dub
Next i
End Sub
'this is the sub
Private Sub NewButton(ByVal ButtonNumber As Integer)
Dim oButton As Button
oButton = New Button
oButton.Enabled = True
oButton.Location = New Point(ButtonNumber + 50, ButtonNumber + 50)
oButton.Name = "MyButton" & ButtonNumber.ToString
oButton.Size = New Size(75, 23)
oButton.Text = "Button" & ButtonNumber.ToString
oButton.Visible = True
oButton.Tag = ButtonNumber
TabControl.SelectedTab.Controls.Add(oButton)
End Sub
I would appreciate it if you guys could suggest what I need to change in order to achieve this functionality.
Thanks for your time
Maybe you button is Under the other controls, try calling oButton.BringToFront() after you add the button to the Tabcontrol controls.