dynamically creating buttons in code in vb2010 - vb.net

I'm working in VB2010 and I think I can create a button array in code; however, I'm struggling to then refer to the created buttons individually to code their click events so that they work at runtime.
Any help would be greatly appreciated. I'm fairly new to vb programmimg so go easy on me!!

Give this a try:
' However many buttons you want
Dim numButtons As Integer = 5
Dim ButtonArray(numButtons) as Button
Dim i As Integer = 0
For Each b As Button in ButtonArray
b = new button
AddHandler b.Click, AddressOf Me.ButtonsClick
b.Tag = "b" & i
' You can also set things like button text in here.
i += 1
Next
Private Sub ButtonsClick(sender As Object, e As System.EventArgs)
' sender is the button that has been clicked. You can
' do what you'd like with it, including cast it as a Button.
Dim currButton As Button = CType (sender, Button)
Select Case currButton.Tag
Case "b0":
' This is the first button in the array. Do things!
Case "b1":
' This is the second button in the array. Do things!
Case "b2":
' Notice a pattern?
'...
End Select
End Sub

On one of the button click events insert something like , button2.click which will perform the same action.
Or you may need to look into addHandler.....

Related

VB DataGridView CellMouseClick event Prevents CellMouseDoubleClick

I'm using Visual Basic to write a WinForm Application. In my DataGridView I have the Selection Mode property set to CellSelect. I am trying to set my DataGrid up so that on a single click, a few textboxes are populated with some data, and on a double click, it will open up a new form and display all kinds of other info.
I have tried both the CellClick + CellDoubleClick events as well as the CellMouseClick + CellMouseDoubleClick however, everytime I double click, the single click event fires first and prevents the doubleclick event from ever firing.
Maybe this is just a lack of understanding on my part and I need to do something different, I thought about just adding a button column and firing the buttonclick event but that will require a lot of re-coding since I hard-coded existing data columns properties such as Column(1...15).visible = false and a lot more. Anyone have any thoughts on how to get both events to fire?
Double Click event
Private Sub DataGridView1_CellDoubleClick(sender As Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseDoubleClick
CallLookup.ShowDialog()
Dim PatientID As String = SelectGrid.Rows(SelectGrid.CurrentRow.Index).Cells("PatientID").Value.ToString
PatientID = CallLookup.patientID2
End Sub
Single Click
Private Sub DataGridView1_CellMouseClick1(sender As Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles DataGridView1.CellMouseClick
Dim reader As SqlClient.SqlDataReader = mycommand.ExecuteReader
While reader.Read
Dispatchtxt2.Text = (reader("PickupDispatchedTime").ToString)
Enroute2Txt.Text = (reader("PickupEnRouteTime").ToString)
OnScene2Txt.Text = (reader("PickupOnSceneTime").ToString)
Transport2Txt.Text = (reader("PickupTransportTime").ToString)
Arrival2Txt.Text = (reader("PickupArrivalTime").ToString)
clear2txt.Text = (reader("PickupClearTime").ToString)
End While
DataGridView1.Refresh()
DataGridView1.InvalidateRow(DataGridView1.CurrentRow.Index)
Else
End If
End Sub
I left a few lines out that were just a data connection

Edit Update DatagridView VB.Net (No Database)

Good day everyone.
I need your help in this project I am into (a Visual Basic program with no database.) It just contains a Datagridview, a Textbox, and three buttons (an "Add" Button, a "Edit" and an "Update" Button).
1 . Is there any way (like using "for loop") to automatically assign DataGridView1.Item("item location") to the one edited and be updated?
2 . Or is it possible to just click an item in the Datagridview then it will be edited at that without passing it to a Textbox, and to be updated at that.
The DataGridViewCellEventArgs variable (e in the method stub the designer will generate for you) of the double click event of the cell has RowIndex and ColumnIndex properties which refer to the position of the cell you clicked.
Save those (in a class variable possibly or a local one if that's all you need) and then refer to them when you update the cell in your DataGridView, possibly like this MyDataGridView.Item(e.ColumnIndex, e.RowIndex) or MyDataGridView.Rows(e.RowIndex).Cells(e.ColumnIndex) where e is the variable from the double click event handler.
For you cell double click event you could have something like this:
Private Sub DataGridView1_CellDoubleClick(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellDoubleClick
Using myEditor As New frmCellEditor(Me.DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value)
If myEditor.ShowDialog() = DialogResult.OK Then
Me.DataGridView1.Item(e.ColumnIndex, e.RowIndex).Value = myEditor.NewCellValue
End If
End Using
End Sub
This will call a new instance of your editor and get a value from you. For the purpose of this demo I have made a form like this:
Public Class frmCellEditor
Public NewCellValue As Integer
Public Sub New(ByVal CurrentCellValue As Object)
InitializeComponent()
Me.TextBox1.Text = CStr(CurrentCellValue)
End Sub
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Me.NewCellValue = CInt(Me.TextBox1.Text)
Me.DialogResult = DialogResult.OK
End Sub
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Call Me.Close()
End Sub
End Class
Which just has two buttons (Button1 = OK, Button2 = Cancel). When you click OK, it just returns the value 1 which then gets set as the value of the cell.
This is a VERY simplistic example, but it should provide you the basics of what you are trying to do.
UPDATE:
I updated the code for the editor interface so it will include handling for passing the value back and forth from the form with your datagridview.
In your project, make a new form called frmCellEditor. This forms has to have two buttons and a textbox (Make sure that the programmatic names match!). Replace the code with the code listed above. You will have to add Imports System.Windows.Forms above the class as well.
Amend the event handler for the cell double click event of your datagrid to pass the cell value when frmCellEditor is constructed (the line going ... New frmCellEditor(...).
How many columns does your DataGridView has?
Based on how you populate your DataGridView, I'll assume only 1.
Declare this on top of your form
Dim i as Integer
On your btnUpdate_Click Event (Just combine your Edit and Update button into One)
SELECT CASE btnUpdate.Text
Case "Update"
With DataGridView1
'Check if there is a selected row
If .SelectedRows.Count = 0 Then
Msgbox "No Row Selected for Update"
Exit Sub
End If
i = .CurrentRow.Index 'Remember the Row Position
Textbox1.Text = .item(0 ,i).value 'Pass the Value to the textbox
.Enabled = False 'Disable DataGridView to prevent users from clicking other row while updating.
btnUpdate.Text = "Save"
End With
Case Else 'Save
DatagridView1.Item(0,i).Value = Textbox1.Text
btnUpdate.Text = "Update"
END SELECT
Thanks for those who contributed to finding answers for this thread. I have not used your solutions for now (maybe some other time). After some research, I've found an answer for problem 2 (more user friendly at that):
2 . Or is it possible to just click an item in the Datagridview then
it will be edited at that without passing it to a Textbox, and to be
updated at that.
Here's what i did:
in Private Sub Form1_Load, just add:
yourDataGridView.EditMode = DataGridViewEditMode.EditOnEnter
in Private Sub yourDataGridView_(whatever event here: DoubleCellClick, CellContentClick, etc.) add:
DataGridView1(e.ColumnIndex, e.RowIndex).[ReadOnly] = False
DataGridView1.BeginEdit(False)

Convert a string to

For example i have a program with 10 buttons and when i press a random one its name is saved to a string and i want to add 1 to the button's name for example if i pressed button1 ill alter the string to say button2 but now i cant use that string because it cant convert string to system.windows.forms.buttons, i have already tried the Me.Controls bu it didnt work for me.
Example:
dim stringy as string
dim integr as integer
dim buton as button
sub procedureee
stringy = stringy.remove(0,6)
integr = val(stringy) + 1
stringy = "Button" & integr
button.backcolor = white
end sub
Button1_Click
stringy = button1
procedureee
/* EDIT */
Im sorry i think i didnt make my sefl clear, everything in this code works for me except "stringy = button1" it says that string cannot be converted to system.windows.forms.button but thats exactly what i want to do, i have a program with 100 buttons and when any button is pressed it sets the value of ("Dim local as button") the variable local= the button pressed, and it works so i take that button.name and remove 1 from it so i get the value of the button above(PS: i have the buttons on a grid and vertically its from 1 to 10 and if i remove 1 il get the name of the button abore ex: button1gA3 becomes Button1gA2) but when i try to do this local2 = stringy it gives me that message(string cannot be converted to system.windows.forms.button) anyone knows how to solve this?
Thanks.
Here you go ...
Private Sub Button_Click(sender As Object, e As EventArgs) Handles Button1.Click, Button2.click
Dim FullButtonName As String = sender.text
Dim ButtonsNumber As String = FullButtonName.Replace("Button", "").Trim
Dim NewButtonNumber As Integer = CType(ButtonsNumber, Integer) + 1
sender.text = "Button " & NewButtonNumber.ToString
End Sub
You can use FindControl() to find a control by name. Note that it is not recursive, and so you'll need to call this method on the direct parent that contains your buttons.

Simple VB, handling many buttons

In my VB solution I have a lot of buttons arranged in a grid. When the program is loaded one of the buttons is randomly set to be the right one (You have to click that one to win). Can anybody point my in the right direction? Because there must be a better way than manually coding every single button, and creating an event handler for every single button.
You don't have to give me a working example, just an overall idea of how this is done.
Thanks.
If you want to arrange the buttons in a grid, either use the TableLayoutPanel or add the buttons directly to the form and calculate their positions. The TableLayoutPanel is useful if you want to arrange the buttons automatically when the form resizes, otherwise adding the buttons directly seems easier to me.
Add the buttons to an array defined at form level to make them easily accessible
Public Const NColumns As Integer = 5, NRows As Integer = 4
Private buttons As Button(,) = New Button(NColumns - 1, NRows - 1) {}
You can add the buttons easily in loops
For ix As Integer = 0 To NColumns - 1
For iy As Integer = 0 To NRows - 1
Dim btn = New Button()
btn.Text = String.Format("{0:d2}{1:d2}", ix, iy)
btn.Location = New Point(leftMargin + ix * xDistance,
topMargin + iy * yDistance)
btn.Size = New Size(buttonWidth, buttonHeight)
AddHandler btn.Click, Addressof Button_Clicked
buttons(ix, iy) = btn
Controls.Add(btn)
Next
Next
You can determine the winning button with a random generator. Define it as form member, not as local variable.
Private randomGenrator As System.Random = New System.Random()
Determine the coordinates
Dim xWins = randomGenrator.Next(NColumns) 'Returns a number between 0 and NColumns-1
Dim yWins = randomGenrator.Next(NRows)
The click handler looks like this
Private Sub Button Button_Clicked(sender As Object, e As EventArgs)
If sender = buttons(xWins, yWins) Then
'You win
Else
'You loose
End
End Sub
First, you said you want a grid of buttons, so you have to have a FlowLayoutPanel control in your form in order to let the buttons you want to add, to be arranged automatically.
Second, you have to make use of a for loop, r any kind of look, in order to add the buttons to be added to previously added 'FlowLayoutPanel'.
class Answers
Dim strAnswerText as string
Dim AnswerFlag as Boolean
End Class
Sub LoadForm(byval a_Answers as Answer())
Dim i as Integer = 0
Dim b as Button
For(i=0;i<NUM_OF_BUTTONS;i++)
b = New Button()
b.Text = "Choice -" & i & "- " & a_Answers(i).strAnswerText
b.Tag = a_Answers(i).AnswerFlag
'Supposing that the FlowLayoutPanel control name is fl
AddHandler b.Click, Addressof Clicked
fl.controls.Add(b)
End For
End Sub
Sub Button Clicked(sender as object, e as EventArgs)
if sender.Tag = True
'True answer
else
'Wrong answer
end if
End Sub

Adding events dynamically

Here's a scernerio that will get what I am trying to accomplish....
Say I have a form with a textbox to enter a number and a button called "Create"
When a user enters a number and clicks create the form gets populated with the number of buttons entered in the textbox and the title of the buttons are labeled by consecutive numbers.
For example if you enter 5 the form will populate with 5 buttons labeled button1, button2, ...button5
When you click on these newly created buttons a messagebox will popup stating the buttons name.
Basically I need to know how to create events and populate them with code I guess
dynamically.
Please respond in a solution for a windows app not web. No JavaScript.
Please can someone respond with a code example this idea is a little foggy to me
'Make sure that the textbox contains a number.
If IsNumeric(TextBox1.Text) Then
'Make sure that it's a positive number.
If CInt(TextBox1.Text) > 0 Then
For i = 1 To CInt(TextBox1.Text)
Dim x As New Button
x.Name = "Button" & i.ToString
x.Top = 100 + (i * 30) 'To avoid stacking.
AddHandler x.Click, AddressOf y 'Add the event here.
'Add it to the form.
Controls.Add(x)
Next
End If
End If
Private Sub y(ByVal sender As System.Object, ByVal e As System.EventArgs)
MsgBox(CType(sender, Button).Name)
End Sub