My Custom-drawn tab doesn't respond to events...

lickuid

Active member
Joined
Nov 6, 2006
Messages
37
Programming Experience
Beginner
Hi everyone... I am very new to GDI+, studying up on it and all... yesterday, I made a tab with the system.drawing and system.drawing.drawing2D namespaces... My code is at the bottom... What's weird is that during build time I can take the control and add it to a form, it'll resize and all like it should, but during runtime, the mousehover and mouseleave events don't create the inteded draw actions... what am I doing wrong?

VB.NET:
Public Class qlTab
    Inherits UserControl

    Dim index As Integer
    Dim title As String
    Dim fntList As FontFamily
    Dim tFont As Font = New Font(fntList.GenericSansSerif, 8)
    Dim cA As Integer = 5 ' curveAmount
    Dim tL(2) As Point ' top left
    Dim tR(2) As Point ' top right
    Dim bL(2) As Point 'bottom left
    Dim bR(2) As Point ' bottom right
    Dim area As Rectangle
    Dim transparent As Color = Color.FromArgb(0, 0, 0, 0)
    Dim barheight As Integer = 6
    Dim glowBarRGB(1) As Color
    Dim tabRGB(1) As Color

    Private Sub qlTab_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Me.MinimumSize = New Size(14, 24)
        With area
            .X = 0
            .Y = 0
            .Width = Me.Width
            .Height = Me.Height
        End With

        tL(0) = New Point(1, 1 + cA)
        tL(1) = New Point(3, 3)
        tL(2) = New Point(1 + cA, 1)

        tR(0) = New Point((Me.Width - 1) - cA, 1)
        tR(1) = New Point((Me.Width - 3), 3)
        tR(2) = New Point((Me.Width - 1), 1 + cA)

        bL(0) = New Point(1 + cA, (Me.Height - 1))
        bL(1) = New Point(2, (Me.Height - 3))
        bL(2) = New Point(0, Me.Height - barheight)

        bR(0) = New Point((Me.Width - 1), Me.Height - barheight)
        bR(1) = New Point((Me.Width - 3), (Me.Height - 3))
        bR(2) = New Point((Me.Width - 1) - cA, (Me.Height - 1))
        glowBarRGB(0) = Color.FromArgb(255, 142, 140, 125)
        glowBarRGB(1) = Color.FromArgb(255, 219, 217, 202)
        tabRGB(0) = Color.FromArgb(255, 250, 249, 245)
        tabRGB(1) = Color.FromArgb(255, 192, 192, 168)

    End Sub

    Private Sub qlTab_MouseHover(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseHover
        glowBarRGB(0) = Color.FromArgb(255, 255, 205, 0)
        glowBarRGB(1) = Color.FromArgb(255, 255, 243, 104)
    End Sub
    Private Sub qlTab_MouseLeave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.MouseLeave
        glowBarRGB(0) = Color.FromArgb(255, 142, 140, 125)
        glowBarRGB(1) = Color.FromArgb(255, 219, 217, 202)
    End Sub
    Private Sub qlTab_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
        tL(0) = New Point(1, 1 + cA)
        tL(1) = New Point(3, 3)
        tL(2) = New Point(1 + cA, 1)

        tR(0) = New Point((Me.Width - 1) - cA, 1)
        tR(1) = New Point((Me.Width - 3), 3)
        tR(2) = New Point((Me.Width - 1), 1 + cA)

        bL(0) = New Point(1 + cA, (Me.Height - 1))
        bL(1) = New Point(2, (Me.Height - 3))
        bL(2) = New Point(0, Me.Height - barheight)

        bR(0) = New Point((Me.Width - 1), Me.Height - barheight)
        bR(1) = New Point((Me.Width - 3), (Me.Height - 3))
        bR(2) = New Point((Me.Width - 1) - cA, (Me.Height - 1))

    End Sub
    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        MyBase.OnPaint(e)
        Dim G As Graphics = e.Graphics
        Dim pen As Pen = New Pen(Color.Transparent)

        Dim glowBar As GraphicsPath = New GraphicsPath
        glowBar.AddLine(New PointF(0, (Me.Height - barheight)), New PointF(Me.Width, (Me.Height - barheight)))
        glowBar.AddCurve(bR)
        glowBar.AddLine(bR(2), bL(0))
        glowBar.AddCurve(bL)
        G.DrawPath(pen, glowBar)
        G.FillPath(New LinearGradientBrush(New Point(0, (Me.Height - barheight)), New Point(0, Me.Height), glowBarRGB(0), glowBarRGB(1)), glowBar)

        Dim tab As GraphicsPath = New GraphicsPath
        tab.AddLine(New Point(0, 0), New Point(Me.Width, 0))
        tab.AddLine(New Point(Me.Width, 0), New Point(Me.Width, (Me.Height - barheight)))
        tab.AddLine(New Point(Me.Width, (Me.Height - barheight)), New Point(0, (Me.Height - barheight)))
        tab.AddLine(New Point(0, (Me.Height - barheight)), New Point(0, 0))
        G.FillPath(New LinearGradientBrush(New Point(0, 0), New Point(0, (Me.Height - barheight)), tabRGB(0), tabRGB(1)), tab)

        G.DrawLine(New Pen(Color.FromArgb(100, 0, 0, 0)), New Point(1, 3), New Point(1, (Me.Height - (barheight + 3))))
        G.DrawLine(New Pen(Color.FromArgb(100, 0, 0, 0)), New Point((Me.Width - 1), 3), New Point((Me.Width - 1), (Me.Height - (barheight + 3))))


    End Sub


End Class
 
In the mousehover and mouseleave events you are only setting some color and not doing anything to cause repaint like using the .Refresh or .Invalidate methods.

Also, you say "tab", if this is related to TabPage control you should inherit from that instead of UserControl.
 
When creating your own custom contols or onwer drawing one you should always override the event you want to use. You have overriden the paint event, but you have used the standard events for MouseHover and MouseLeave try overriding them instead. Also i would be using the UserControl class, when creating my own controls i always inherit from the base class control. UserControl doesn't seem to always do what you ask, strange that.

EDIT: JohnH beat me to it, and he is quite correct about calling Invalidate in those methods.
 
Well, That certainly does the trick
Thanks you two!

One thing though... It doesn't really respond to the mousehover immediately, it's delayed a fraction of a second, but i can tell... any solution to that?
 
That's how MouseHover works, instead use the MouseEnter event. (not MouseMove unless you got a good reason to update code every pixel mouse moves)
 
You would have a boolean to determine if the mousemove was necessary or not. You can try the mouse enter but seeing as it doen't always fire your control could end up in a state that you don't want.
 
When does MouseEnter event not fire? I have not seen this happen.
 
MouseEnter and MouseLeave suffer the same problem when passing the mouse pointer over the region using the event very quickly. For some reason the event seems to get 'missed' Thats why the mousemove event is more secure when it comes to hittesting.
 
Back
Top