Adding Controls at Runtime problem
I have an odd problem that is really frustrating. I've created buttons at runtime and set up the handlers. When the user clicks the created buttons, I read the sender.text and respond to it. See below....
If sender.text.ToString = WSAnswer Then
MessageBox.Show("Yes")
PlayWhatSays()
Else
MessageBox.Show("Nope" & " " & WSAnswer & " " & sender.text.ToString)
End If
The code works well except when I click the last button created. When I do that, for some strange reason it works as planned once then for some reason the program runs the event for a second time as if the user clicked the button twice. This occurs only when I click the last button created and happens for both a correct and an incorrect answer. I have walked through this a number of time and I know that I haven't created 2 buttons on the same position. Also the PlayWhatSays event does not trigger the created buttons click event. Any help?
Thanks
Add controls at runtime poroblem
Here is the code to create and remove the buttons and below that is the button click
Private Sub AddWhatSaysButtons()
'this sub adds what says text boxes and fills them
Dim z As Integer
Dim i As Integer
Dim position As Point
Dim iTop As Integer = 24
Dim iLeft As Integer = 16
Dim iTextBox As Integer = clsQD.WhatSaysCount - 1
Dim iStandardWidth As Double = 54
Dim iStandardHeight As Double = 74
Dim fnt As New Font("Microsoft Sans Serif", 12, FontStyle.Regular)
Try
For z = 0 To Me.Controls.Count - 1
If Me.Controls(z).GetType Is GetType(System.Windows.Forms.Panel) Then
If Me.Controls(z).Name.ToString = "pnlWhatSays" Then
PanelWSIndex = z 'holds the number of the control
For i = 0 To iTextBox
Select Case i
Case Is = 0
position.X = 16
position.Y = 24
Case Is = 10
position.X = 16
position.Y = 64
Case Is = 20
position.X = 16
position.Y = 104
Case Is = 30
position.X = 16
position.Y = 144
End Select
BTN = New Button
With BTN
.Size = New Size(54, 34)
.Location = position
.Name = "TB" & i.ToString
.Tag = "Added"
.Text = clsQD.TheWhatSaysLetter(i)
.Font = fnt
.BackColor = Color.Yellow
End With
position.X += 68
Me.Controls(PanelWSIndex).Controls.Add(BTN)
AddHandler BTN.Click, New System.EventHandler(AddressOf BTN_Click)
Next
Exit For
End If
End If
Next
Catch ex As Exception
End Try
End Sub
Private Sub RemoveWhatSaysButtons()
Dim z As Integer
Dim i As Integer
Dim ctlRemove() As Control
'this removes the buttons and handlers when the user selects a new help word
Try
If Me.Controls(PanelWSIndex).Controls.Count > 2 Then 'change when control count changes
ReDim ctlRemove(Me.Controls(PanelWSIndex).Controls.Count - 2)
For i = 0 To Me.Controls(PanelWSIndex).Controls.Count - 1
If Not Me.Controls(PanelWSIndex).Controls(i).Tag = "Keep" Then
ctlRemove(z) = Me.Controls(PanelWSIndex).Controls(i)
z += 1 'only move up ctlRemove tally
End If
Next
For z = 0 To UBound(ctlRemove) - 1
Me.Controls(PanelWSIndex).Controls.Remove(ctlRemove(z))
Console.Write(ctlRemove(z).Name)
RemoveHandler BTN.Click, AddressOf BTN_Click
Next
End If
Catch
UnhandledExceptionHandler()
End Try
End Sub
Private Sub BTN_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTN.Click
If sender.text.ToString = WSAnswer Then
MessageBox.Show("Yes")
PlayWhatSays()
Else
MessageBox.Show("Nope" & " " & WSAnswer & " " & sender.text.ToString)
End If
End Sub
Adding controls at runtime
Anyone:
I wrote small program that isolates the problem I have with creating controls at runtime. (I have no problem creating and
removing controls---its the click events I'm having trouble with)
To recreate the program Set up a form with a panel(size it large). Add 3 buttons, a text box "tbInt" and a label "lblAns" (all outside the panel) to the form. Paste the code below. Type a number into the text box < 20, click Button1 to add the buttons, click button3 to chose a random number click on the number selected on the yellow created button. It will work fine until the
number selected is the same as the last button created---then the BtnNew.click event will fire twice--
Why?????
(Button2 removes the created buttons.)
Thanks a Lot!!
Public Class Form1
Inherits System.Windows.Forms.Form
Private WithEvents BTNNew As Button
Private PanelWSIndex As Integer
Private stAnswer As String
----------------------------------------------------------------------------
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
'call to add the buttons
AddButtons()
End Sub
Private Sub AddButtons()
'this sub adds and spaces buttons and text within the panel
Dim z As Integer
Dim i As Integer
Dim position As Point
Dim iButtonCount As Integer = CInt(tbInt.Text)
Dim fnt As New Font("Microsoft Sans Serif", 12, FontStyle.Regular)
Try
For z = 0 To Me.Controls.Count - 1 'find the panel I'm looking for
If Me.Controls(z).GetType Is GetType(System.Windows.Forms.Panel) Then
PanelWSIndex = z 'holds the number of the panel control
For i = 0 To iButtonCount
Select Case i
Case Is = 0
position.X = 16
position.Y = 24
Case Is = 10
position.X = 16
position.Y = 64
BTNNew = New Button
With BTNNew
.Size = New Size(54, 34)
.Location = position
.Name = "TB" & i.ToString
.Tag = "Added"
.Text = i.ToString
.Font = fnt
.BackColor = Color.Yellow
End With
position.X += 68 'spaces location of control
Me.Controls(PanelWSIndex).Controls.Add(BTNNew)
AddHandler BTNNew.Click, New System.EventHandler(AddressOf BTNNew_Click)
Next
Exit For
End If
Next
Catch ex As Exception
End Try
End Sub
Private Sub RemoveButtons()
Dim z As Integer
Dim i As Integer
Dim t As Integer
Dim ctlRemove() As Control
'this removes the buttons and handlers when the user selects a new number
Try
ReDim ctlRemove(Me.Controls(PanelWSIndex).Controls.Count - 1)
For i = 0 To Me.Controls(PanelWSIndex).Controls.Count - 1
If Not Me.Controls(PanelWSIndex).Controls(i).Tag = "Keep" Then
ctlRemove(z) = Me.Controls(PanelWSIndex).Controls(i)
z += 1 'only move up ctlRemove tally
End If
Next
For t = 0 To UBound(ctlRemove)
Me.Controls(PanelWSIndex).Controls.Remove(ctlRemove(t))
Console.Write(ctlRemove(t).Name)
RemoveHandler BTNNew.Click, AddressOf BTNNew_Click
Next
Catch
MessageBox.Show(Err.Description)
End Try
stAnswer = "0"
tbInt.Text = "0"
End Sub
Private Sub BTNNew_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BTNNew.Click
If sender.text.ToString = stAnswer Then
MessageBox.Show("Yes")
'Beep()
Else
MessageBox.Show("Nope" & " " & stAnswer & " " & sender.text.ToString)
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
RemoveButtons()
End Sub
Function ChooseNumber() As String
'will select a random number to be used as the in the btnNew click event for
'the answer
Dim rnd As New System.Random
Dim stSelected As String
Dim i As Integer
Dim imax As Integer = CInt(tbInt.Text) + 1
If Not imax = 0 Then
Randomize()
i = rnd.Next(0, imax)
stSelected = CStr(i)
Return stSelected 'returns the answer
End If
End Function
Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
stAnswer = ChooseNumber()
lblAns.Text = stAnswer
End Sub
End Class