Ghost button pushing... WHY????

trend

Centurion
Joined
Oct 12, 2004
Messages
171
I have written some code that automatically adds buttons based on the user selection.

But my problem is.. buttons seem to be pushed when I don't press them.

Here is my code..

Visual Basic:
Public Class Form1
    Inherits System.Windows.Forms.Form
    Dim button0 As New Button
    Dim button1 As New Button
    Dim button2 As New Button
    Dim button3 As New Button
    Dim button4 As New Button
    Dim button5 As New Button
    Dim ButtonName(30) As String



#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call

    End Sub

    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 266)
        Me.Name = "Form1"
        Me.Text = "Form1"

    End Sub

#End Region


    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

        ButtonName(0) = "Black"
        ButtonName(1) = "Color"
        Call AddButtons(ButtonName)


    End Sub


    Private Sub AddButtons(ByVal Buttons() As String)
        Dim ButtonX As Integer
        Dim ButtonY As Integer

        'this clears all buttons in this function
        Dim ControlsToRemove As New ArrayList
        For Each Item As Control In Me.Controls
            Try
                If DirectCast(Item.Tag, String) = "Remove" Then
                    ControlsToRemove.Add(Item)
                End If
            Catch ex As Exception
            End Try
        Next
        For Each Item As Object In ControlsToRemove
            Me.Controls.Remove(DirectCast(item, Control))
        Next



        'see if we are past selecting brand/color and sets ButtonY accordingly
        ButtonY = 100
        ButtonX = 24



        If Buttons(0) <> "" Then
            With button0
                .Size = New Size(120, 120)
                .Location = New Point(ButtonX, ButtonY)
                .Text = Buttons(0)
                .Tag = "Remove"
                'causes the newbtnClick procedure to fire on the click event.
                AddHandler button0.Click, AddressOf Button0_Click
            End With
            Me.Controls.Add(button0)
        End If

        If Buttons(1) <> "" Then
            ButtonX = ButtonX + 144
            With button1
                .Size = New Size(120, 120)
                .Location = New Point(ButtonX, ButtonY)
                .Text = Buttons(1)
                .Tag = "Remove"
                'causes the newbtnClick procedure to fire on the click event.
                AddHandler button1.Click, AddressOf Button1_Click
            End With
            Me.Controls.Add(button1)
        End If

        If Buttons(2) <> "" Then
            ButtonX = ButtonX + 144
            With button2
                .Size = New Size(120, 120)
                .Location = New Point(ButtonX, ButtonY)
                .Text = Buttons(2)
                .Tag = "Remove"
                'causes the newbtnClick procedure to fire on the click event.
                AddHandler button2.Click, AddressOf Button2_Click
            End With
            Me.Controls.Add(button2)
        End If

        If Buttons(3) <> "" Then
            ButtonX = ButtonX + 144
            With button3
                .Size = New Size(120, 120)
                .Location = New Point(ButtonX, ButtonY)
                .Text = Buttons(3)
                .Tag = "Remove"
                'causes the newbtnClick procedure to fire on the click event.
                AddHandler button3.Click, AddressOf Button3_Click
            End With
            Me.Controls.Add(button3)
        End If

        If Buttons(4) <> "" Then
            ButtonX = 24 'reset buttonx so new buttonset will new line
            ButtonY = 250
            With button4
                .Size = New Size(120, 120)
                .Location = New Point(ButtonX, ButtonY)
                .Text = Buttons(4)
                .Tag = "Remove"
                'causes the newbtnClick procedure to fire on the click event.
                AddHandler button4.Click, AddressOf Button4_Click
            End With
            Me.Controls.Add(button4)
        End If

        If Buttons(5) <> "" Then
            ButtonX = ButtonX + 144
            With button5
                .Size = New Size(120, 120)
                .Location = New Point(ButtonX, ButtonY)
                .Text = Buttons(5)
                .Tag = "Remove"
                'causes the newbtnClick procedure to fire on the click event.
                AddHandler button5.Click, AddressOf Button5_Click
            End With
            Me.Controls.Add(button5)
        End If


    End Sub



    Private Sub Button0_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Call AddtoUserWantsArray(button0.Text)
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Call AddtoUserWantsArray(button1.Text)
    End Sub
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Call AddtoUserWantsArray(button2.Text)
    End Sub
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Call AddtoUserWantsArray(button3.Text)
    End Sub
    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Call AddtoUserWantsArray(button4.Text)
    End Sub
    Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Call AddtoUserWantsArray(button5.Text)
    End Sub




    Private Sub AddtoUserWantsArray(ByVal AddThis As String)



        MsgBox("Button Pressed", MsgBoxStyle.Information)

        If AddThis = "Black" Then

            ButtonName(0) = "Yellow"
            ButtonName(1) = "Green"
            Call AddButtons(ButtonName)

        ElseIf AddThis = "Color" Then
            ButtonName(0) = "Red"
            ButtonName(1) = "Green"
            Call AddButtons(ButtonName)
        ElseIf AddThis = "Yellow" Then
            ButtonName(0) = "Yellow"
            ButtonName(1) = "Red"
            Call AddButtons(ButtonName)
        ElseIf AddThis = "Red" Then
            ButtonName(0) = "Yellow"
            ButtonName(1) = "Color"
            Call AddButtons(ButtonName)
        ElseIf AddThis = "Green" Then
            ButtonName(0) = "Black"
            ButtonName(1) = "Color"
            Call AddButtons(ButtonName)

        End If



    End Sub

End Class

You can just copy and past the code in.. and thatis it..

thanks for any help! This has been driving me nuts for days :/

Lee
 
If you want to test out the code..click on "black" button then any button pressed after that causes the button to be pressed a couple times.

any ideas?

thanks-Lee
 
As you are only using two buttons (Button0 and Button1) every time you call AddHandler and pass in the click event you are binding to the event again.
It may be more help if you give an idea of what you are trying to do as at the moment your code looks unnecessarily convoluted; why hard code 6 buttons but use an array for names? why hard-code 6 button click handlers rather than just one that handles all buttons? The AddButtons method could really use a loop rather than cut and paste to handle each button condition as well.
 
When you remove a button from the form, also remove the handler. The RemoveHandler keyword works like the AddHandler keywork only... it removes and existing handler. If you are going to re-use a button, you don't need to remove the handler, but be sure not to re-add it.
 
Less is more

Here. I uh... rewrote your code. Don't take offense; I did it for the sake of giving you some pointers.

Visual Basic:
Public Class Form1
    Inherits System.Windows.Forms.Form
'
    'Since the buttons all work exactly the same, we can use an array, which
    'will later simplify the process of creation
    Dim Buttons(5) As Button
    Dim ButtonName(30) As String
'
    ReadOnly ButtonSize As Size = New Size(120, 120)
'
#Region " Windows Form Designer generated code "
'
    Public Sub New()
        MyBase.New()
'
        'This call is required by the Windows Form Designer.
        InitializeComponent()
'
        'Add any initialization after the InitializeComponent() call
'
    End Sub
'
    'Form overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub
'
    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer
'
    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13)
        Me.ClientSize = New System.Drawing.Size(292, 266)
        Me.Name = "Form1"
        Me.Text = "Form1"
'
    End Sub
'
#End Region
'
'
    Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'
        ButtonName(0) = "Black"
        ButtonName(1) = "Color"
        Call AddButtons(ButtonName)
'
    End Sub
'
'
    Private Sub AddButtons(ByVal ButtonNames() As String)
'
        'this clears all buttons in this function
        Dim ControlsToRemove As New ArrayList
        For Each Item As Control In Me.Controls
            Try
                If DirectCast(Item.Tag, String) = "Remove" Then
                    ControlsToRemove.Add(Item)
                End If
            Catch ex As Exception
                'Ignore exceptions
            End Try
        Next
        For Each Item As Object In ControlsToRemove
            'Remove the control AND the handler
            Me.Controls.Remove(DirectCast(item, Control))
            RemoveHandler DirectCast(item, Control).Click, AddressOf Button_Click
        Next
'
        'Use the declaration/initialization syntax for easier reading
        Dim ButtonX As Integer = 24
        Dim ButtonY As Integer = 100
'
        'Since the code that creates buttons is almost the same for each button,
        'we can use a loop and cut the code in 1/6
        For i As Integer = 0 To 5
            If ButtonNames(i) <> "" Then
                Buttons(i) = New Button 'Create new button
                With Buttons(i)
                    .Size = ButtonSize
                    .Location = New Point(ButtonX, ButtonY)
                    ButtonX += 144
                    .Text = ButtonNames(i)
                    .Tag = "Remove"
                End With
                AddHandler (Buttons(i)).Click, AddressOf Button_Click
                Me.Controls.Add(Buttons(i))
            End If
        Next
    End Sub
'
'
'
    Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        'We can dynamically handle the click for any button in one sub
        'because the button that was clicked is passed as "sender".
        Call AddtoUserWantsArray(DirectCast(sender, Button).Text)
    End Sub
'
    Private Sub AddtoUserWantsArray(ByVal AddThis As String)
        MsgBox("Button Pressed", MsgBoxStyle.Information)
'
        'Select cases are easier to read and, again with the laziness, save typing
        Select Case AddThis
            Case "Black"
                ButtonName(0) = "Yellow"
                ButtonName(1) = "Green"
            Case "Color"
                ButtonName(0) = "Red"
                ButtonName(1) = "Green"
            Case "Yellow"
                ButtonName(0) = "Yellow"
                ButtonName(1) = "Red"
            Case "Red"
                ButtonName(0) = "Yellow"
                ButtonName(1) = "Color"
            Case "Green"
                ButtonName(0) = "Black"
                ButtonName(1) = "Color"
        End Select
'
        'I moved this out of the select case because it is called under all specified cases.
        'Saves five lines of code. Doin' it the lazy way. Or... code smarter, not harder.
        Call AddButtons(ButtonName)
    End Sub
End Class

The file became about 100 lines shorter. When you program long enough, it seems like all you can think about is efficiency. Use less code... use less memory... use less cpu... less is more.
 
marble_eater said:
Here. I uh... rewrote your code. Don't take offense; I did it for the sake of giving you some pointers.

The file became about 100 lines shorter. When you program long enough, it seems like all you can think about is efficiency. Use less code... use less memory... use less cpu... less is more.

the reason this code might seem really bloated is.. this is just the screwed up part from my larger project.. but now it works! This new code answers 2 other of my silent questions.. how to use case/select and how to use one on_button_click function.


thanks!
 
Last edited:
Back
Top