Custom buttons on windows forms

Craig

Well-known member
Joined
Oct 15, 2005
Messages
110
Location
United Kingdom
Programming Experience
Beginner
Hello there, i have seen an app that was made in vb.net and i was wondering how to emulate this effect. The images below are what I am trying to create, and what I suspect might be quite difficult is that the mouse over and mouse down effects differ in relation to their respective background colours. I don't really have any idea where to start so all suggestions are appreciated.
blue2rz.gif
tan6xz.gif


Thanks, Craig.
 
You could do that simply by changing the BackColor of the Button on the MouseEnter, MouseDown, MouseUp and MouseLeave events. Doing it that way may not be completely professional looking though. To do a really complete job you'd have to inherit the Button class and provide your own drawing functionality on those events. Same principle but more complex due to the detail.
 
MSDN first, then Google. My advice: just stick to the standard UI for a while until you have a better grounding in the language. In my experience it seems that the desire to have a fancy UI is inversely proportional to the ability to create it. Maybe as you learn more about what's involved you realise that it's just not worth the trouble in most cases.
 
Well the functionality of the program I'm making is working great and the feedback of the users is that it looks a bit too bland.. and i agree with them.

ok i've read up about custom controls and i'm stuck in a rutt

VB.NET:
    Private OldColor As Color

    Private Sub TB_MouseEnter(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.MouseEnter
        OldColor = MyBase.BackColor
        Me.BackColor = ControlPaint.Light(Me.BackColor)
    End Sub

    Private Sub TB_MouseLeave(ByVal sender As Object, _
ByVal e As System.EventArgs) Handles MyBase.MouseLeave
        Me.BackColor = OldColor
    End Sub
This is all very basic at the moment but the problem is that I'm trying to handle the mousedown and mouseup events with:

VB.NET:
Private sub TB_MouseDown(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.MouseDown
and
VB.NET:
Private sub TB_MouseUp(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.MouseUp

But nope it is having problems with MyBase.MouseDown/Up
 
When you inherit a class you do not handle its events internally. You override the method that raises the event. For instance, in the case of the MouseDown event you would override the OnMouseDown method:
VB.NET:
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
    'Do your custom processing here.

    'Call the base implementation, which will actually do the job of raising the event.
    MyBase.OnMouseDown(e)
End Sub
I must ask, have you enabled visual styles in your app to give it that XP look or does it have the old Windows Classic look?
 

Attachments

  • VisualStyles.JPG
    VisualStyles.JPG
    23.6 KB · Views: 90
at the moment i have the windows classic look..

Ive downloaded visualstyles from your sig, added reference to the dll, also added this code into my form1:

VB.NET:
    Shared VSContext As Skybound.VisualStyles.VisualStyleContext

    Public Shared Sub Main()
        VSContext = Skybound.VisualStyles.VisualStyleContext.Create
        Application.Run(New Form1)
    End Sub
Set Sub Main() as the startup

I also added a VisualStylesFilter to my form and set the VisualStyleEnhanced to yes

But that doesnt work :confused:
 
Last edited:
Craig, just in case you do want to create your own buttons here's a quick sample i just knocked up......

Add a new class that inherits from control. Paste the following code. Sorry if it's glitchy, just it's from memory....

In the classes contructor...

VB.NET:
SetStyle(controlstyles.AllPaintingInWmPaint,True)
SetStyle(ControlStyles.DoubleBuffer,true)
SetStyle(ControlStyles.UserPaint,True)


Then in the main body of the class paste the following.. As i have said it's all from memory so i can't guarentee the accuarcy of the code....


VB.NET:
Private _GradientStartColor as color = Color.Blue
Private _GradientEndColor as color = Color.Red
Private Mode as LinearGradientMode = LinearGradientMode.Horizontal
Private DrawFocusRectangle as Boolean = false
 
Public property GradientStartColor as color
Get
Return me._GradientStartColor
End Get
Set (byval Value as color)
me._GradientStartColor = value
Me.Invalidate
End Set
End Poprerty
 
Public Property GradientEndColor as color
Get 
Return Me._GradientEndColor
End Get
Set (byval Value as color)
Me._GradientEndColor = value
Me.Invalidate
End Set 
End Property
 
Public Property GradientMode as LinearGradientMode
Get
Return Me.Mode
End Get
Set(Byval Value as linearGradientMode)
Me.Mode = value
me.Invalidate
End Set
End Property
 
Protected Overrides Sub Paint(Byval e as system.windows.forms.PainteventArgs)
 
Mybase.Onpaint(e)
Din Rc as rectangle = me.clientrectangle
Rc.inflate(-1,-1)
 
Dim ButtonBrush as new LinearGradientBrush(rc,me._gradientStartColor,Me.GradientEndColor,Me.Mode)
 
e.graphics.fillrectangle(buttonbrush,rc)
 
buttonbrush.dispose
 
e.graphics.drawrectangle(pens.black,rc)
 
If me.drawfocusrectangle then
 
rc.inflate(-3,-3)
 
dim focuspen as new pen(color.black,-1)
 
focuspen.penstyle = penstyle.dot
 
e.graphics.drawrectangle(focuspen,rc)
 
focuspen.dispose
end if
end sub
 
 
Protected Overrides Sub OnMouseEnter(Byval e as eventargs)
 
Mybase.OnmouseEnter(e)
Me.DrawFocusRectangle = True
me.invalidate
end sub
 
Protected Overrides Sub OnMouseLeave(byval e as eventargs)
 
mybase.onmouseleave(e)
Me.DrawFocusRectangle = false
me.invalidate
End sub

You will now have some new properties to play with in this control. GradientStartColor, gradientEndColor and mode. They will appear in the 'Misc' Section of the properties window and they will also show up in intellisense. This is a very basic implementation of a rollover effect but the principle is sound, and you should be able to expand on it.
 
You don't have to use that VisualStyles component for most things. It just fixes some of the issues in the in-built visual style support of VS.NET 2003. All I did to change the look of the form on the left was set the FlatStyle property of the controls, other than the TextBox, to System and then add this code to the startup form:
VB.NET:
Public Shared Sub Main()
    Application.EnableVisualStyles()
    Application.DoEvents()
    Application.Run(New Form1) 'substitute the name of your startup form.
End Sub
That will take care of the basics. That VisulaStyles component is useful if you want to overcome some of VS.NET's visual style shortcomings. These include:

No images on Buttons
TabPages show incorrect BackColor
No theme support for NumericUpDown and DomainUpDown

If you don't need images on Buttons and you aren't using TabControls or UpDown controls then you probably don't need the VisualStyles component. I actually haven't used the newest version so I might give a whirl now.
 
Hah.. well there you go it's because my windows theme itself was a windows classic one, if i change it to XP it works :p

If I wanted this to work on other users' systems would I have to include the skybound dll to my setup project?
 
Vis781, I have this code here but there are a few errors that i will highlight in red and reason in blue:

VB.NET:
Public Class UserControl1
    Inherits System.Windows.Forms.Control

'windows generated code


[COLOR=Red]SetStyle[/COLOR](controlstyles.AllPaintingInWmPaint,True)[COLOR=Blue] 'Declaration Expected[/COLOR]
[COLOR=Red]SetStyle[/COLOR](ControlStyles.DoubleBuffer,true)[COLOR=Blue] 'Declaration Expected[/COLOR]
[COLOR=Red]SetStyle[/COLOR](ControlStyles.UserPaint,True)[COLOR=Blue] 'Declaration Expected[/COLOR]

    Private _GradientStartColor As Color = Color.Blue
    Private _GradientEndColor As Color = Color.Red
    Private Mode As [COLOR=Red]LinearGradientMode [/COLOR]= LinearGradientMode.Horizontal [COLOR=Blue]'Type LinearGradientMode is not defined[/COLOR]
    Private DrawFocusRectangle As Boolean = False

    Public Property GradientStartColor() As Color
        Get
            Return Me._GradientStartColor
        End Get
        Set(ByVal Value As Color)
            Me._GradientStartColor = Value
            Me.Invalidate()
        End Set
    End Property


    Public Property GradientEndColor() As Color
        Get
            Return Me._GradientEndColor
        End Get
        Set(ByVal Value As Color)
            Me._GradientEndColor = value
            Me.Invalidate()
        End Set
    End Property

    Public Property GradientMode() As [COLOR=Red]LinearGradientMode [/COLOR][COLOR=Blue]'Type LinearGradientMode is not defined[/COLOR]
        Get
            Return Me.Mode
        End Get
        Set(ByVal Value As [COLOR=Red]linearGradientMode[/COLOR]) [COLOR=Blue]'Type LinearGradientMode is not defined[/COLOR]
            Me.Mode = Value
            Me.Invalidate()
        End Set
    End Property

    Protected Overrides Sub [COLOR=Red]Paint[/COLOR](ByVal e As System.windows.forms.PaintEventArgs) [COLOR=Blue]'sub Paint conflicts with event paint in the base class Control and so should be declared as Shadows[/COLOR]

        MyBase.OnPaint(e)
        Dim Rc As Rectangle = Me.ClientRectangle
        Rc.inflate(-1, -1)

        Dim ButtonBrush As New [COLOR=Red]LinearGradientBrush[/COLOR](rc, Me._GradientStartColor, Me.GradientEndColor, Me.Mode) [COLOR=Blue]'Type LinearGradientMode is not defined[/COLOR]

        e.Graphics.FillRectangle(ButtonBrush, rc)

        ButtonBrush.dispose()

        e.Graphics.DrawRectangle(Pens.Black, rc)

        If Me.DrawFocusRectangle Then

            rc.inflate(-3, -3)

            Dim focuspen As New Pen(Color.Black, -1)

            [COLOR=Red]focuspen.penstyle [/COLOR]= [COLOR=Red]penstyle[/COLOR].dot [COLOR=Blue]'penstyle is not a member of System.Drawing.Pen[/COLOR]

            e.Graphics.DrawRectangle(focuspen, rc)

            focuspen.Dispose()
        End If
    End Sub


    Protected Overrides Sub OnMouseEnter(ByVal e As EventArgs)

        MyBase.OnMouseEnter(e)
        Me.DrawFocusRectangle = True
        Me.Invalidate()
    End Sub

    Protected Overrides Sub OnMouseLeave(ByVal e As EventArgs)

        MyBase.OnMouseLeave(e)
        Me.DrawFocusRectangle = False
        Me.Invalidate()
    End Sub

End Class
Help is much appreciated
 
The 'setstyle' parts should be placed in the classes constructor. You then need to import the drawing2d namespace

imports system.drawing.drawing2d

I think the Paint sub should be OnPaint.
 
Back
Top