Problem on changing button's color

candice

Active member
Joined
Jan 23, 2007
Messages
30
Programming Experience
Beginner
Hi guys,
What I wanna do now is to change the button's color when the button is clicked, and resume its original color when other button being clicked.
Noted that on my form I have many buttons, but I only want the above condition happens on 3 buttons of them. It's a bit like a "button group"
So it will be easy to figure out which button is the last one I clicked of them three. Say, that button's color will be the changed color and the other two will have their original color.
I tried to use the following code to achieve this:
VB.NET:
Private Sub ColorButtons_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click, Button2.Click, Button3.Click 

        For Each b As Button In Me.Controls 
            If b.Tag Is "xx" Then b.BackColor = Color.Green 
        Next 
        CType(sender, Button).BackColor = Color.Red 

    End Sub
But when I run the program I encounter an exception: InvalidCastException was unhandled
"Unable to cast object of type 'System.Windows.Forms.PictureBox' to type 'System.Windows.Forms.Button'." in the line
VB.NET:
For Each b As Button In Me.Controls

On my form, I not only have several buttons, but also have a few picture boxes. I tried to use "If TypeOf b Is System.Windows.Forms.Button Then" to modify it. But if I put it inside the for each loop, the exception is still there, and if I put it outside the for each loop, b is not declared in the statement.

Could anybody help me out? Thanks a lot!!
 
i would advise that you create your own button control, and on the OnMouseEnter or OnClick Events, invalidate the control; and then using a boolean you have set previously to show that you have clicked something, change the color of it in OnPaint... or maybe on the mouse down event rather than the on click even.

for example:

VB.NET:
public class NewButton inherits System.Windows.Forms.Button
 
private IsClicking as Boolean = true
 
      public overrides sub OnMouseDown(....)
           IsClicking=True
           Me.Invalidate() 'note it is better to invalidate the region of  the 
          'button rather than just plain invalidate as the normal invalidate will .
            'invalidate EVERYTHING on the form... not just your button. big 
            'performance hit depending on how many controls you have. if you 
            'want clarification let me know :)
      end sub
 
      private overrides sub onpaint(byval p as painteventargs)
 
            if isclicking then
                p.fillrectangle(brushes.black,p.cliprectangle)
            else
                p.fillrectangle(brushes.grey,p.cliprectangle) 'i am assuming grey is default button colour
            end if
 
      end sub
 
      private overrides sub OnMouseLeave(...)
          isclicking=false
          me.invalidate()
 
      end sub
End class

note that you could substitute the onmouseleave event for the mousebuttonup event if you prefer

anything else (clarification for instance) you need help with, just let me know

cheers
adam
 
I would use RadioButton controls that have this option group behaviour by default, and if you want you can set the property Appearance=Button.
 
candice,
Try this me.controls is too generic and cannot be distinguished between control types.

VB.NET:
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
    Handles Button1.Click, Button2.Click, Button3.Click
        Dim con As Control
        For Each con In Me.Controls
            If (con.GetType.ToString = "System.Windows.Forms.Button") _
            And ((con.Text = "Button1") Or (con.Text = "Button2") _
            Or (con.Text = "Button3")) Then
                con.BackColor = Color.Green
            End If
        Next
        DirectCast(sender, Button).BackColor = Color.Red
    End Sub
 
Last edited:
If (con.GetType.ToString = "System.Windows.Forms.Button")
Do this instead:
VB.NET:
If TypeOf con Is Button
Also if you would choose this approach the looping would be rather redundant compared to this doing the same:
VB.NET:
Button1.BackColor = Color.Blue
Button2.BackColor = Color.Blue
Button3.BackColor = Color.Blue
DirectCast(sender, Button).BackColor = Color.Red
 

Latest posts

Back
Top