0

I have created a custom tab control.The codes are : THE CODE IS KINNDA HUGE,SO PLEASE BE PATIENT TO READ THE ENTIRE CODE

Public Class mytab
Inherits System.Windows.Forms.TabControl

Dim MainColor As Color
Dim TextColor As Color
Dim LightTheme As Boolean
Public Property UseLightTheme() As Boolean
    Get
        Return LightTheme
    End Get
    Set(state As Boolean)
        LightTheme = state
        Refresh()
    End Set
End Property

Public Property TabColor As Color
    Get
        Return MainColor
    End Get
    Set(col As Color)
        MainColor = col
        Refresh()
    End Set
End Property

Public Property FontColor As Color
    Get
        Return TextColor
    End Get
    Set(col As Color)
        TextColor = col
        Refresh()
    End Set
End Property
Sub New()
    SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.ResizeRedraw Or ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer, True)
    DoubleBuffered = True
    Anchor = AnchorStyles.Top And AnchorStyles.Right And AnchorStyles.Bottom And AnchorStyles.Left
    SizeMode = TabSizeMode.Fixed
    ItemSize = New Size(100, 29)
    Size = New Size(400, 250)
    MainColor = Color.FromArgb(59, 151, 241)
    TextColor = Color.White
    LightTheme = False
    Alignment = TabAlignment.Top
End Sub

Function ToPen(ByVal color As Color) As Pen
    Return New Pen(color)
End Function

Function ToBrush(ByVal color As Color) As Brush
    Return New SolidBrush(color)
End Function

Protected Overrides Sub onpaint(ByVal e As PaintEventArgs)
    Dim B As New Bitmap(Width, Height)
    Dim G As Graphics = Graphics.FromImage(B)

    'tabpage color
    If LightTheme = False Then
        Try : SelectedTab.BackColor = Color.Azure : Catch : End Try

        G.Clear(Color.Azure)
    Else
        Try : SelectedTab.BackColor = Color.FromArgb(80, 80, 97) : Catch : End Try
        G.Clear(Color.FromArgb(80, 80, 97))
    End If

    'tab bar
    If LightTheme = False Then
        If Alignment = TabAlignment.Top Then
            G.FillRectangle(New SolidBrush(Color.FromArgb(80, 80, 97)), New Rectangle(0, 0, Width, ItemSize.Height + 5))
        ElseIf Alignment = TabAlignment.Bottom Then
            G.FillRectangle(New SolidBrush(Color.FromArgb(255, 255, 255, 255)), New Rectangle(0, Height - ItemSize.Height, Width, ItemSize.Height))
        ElseIf Alignment = TabAlignment.Left Then
            G.FillRectangle(New SolidBrush(Color.FromArgb(255, 255, 255, 255)), New Rectangle(0, 0, ItemSize.Height, Height))
        ElseIf Alignment = TabAlignment.Right Then
            G.FillRectangle(New SolidBrush(Color.FromArgb(255, 255, 255, 255)), New Rectangle(Width - ItemSize.Height, 0, ItemSize.Height, Height))
        End If
    Else
        If Alignment = TabAlignment.Top Then
            G.FillRectangle(New SolidBrush(Color.FromArgb(80, 80, 97)), New Rectangle(0, 0, Width, ItemSize.Height + 5))
        ElseIf Alignment = TabAlignment.Bottom Then
            G.FillRectangle(New SolidBrush(Color.FromArgb(255, 200, 200, 200)), New Rectangle(0, Height - ItemSize.Height, Width, ItemSize.Height))
        ElseIf Alignment = TabAlignment.Left Then
            G.FillRectangle(New SolidBrush(Color.FromArgb(255, 200, 200, 200)), New Rectangle(0, 0, ItemSize.Height, Height))
        ElseIf Alignment = TabAlignment.Right Then
            G.FillRectangle(New SolidBrush(Color.FromArgb(255, 200, 200, 200)), New Rectangle(Width - ItemSize.Height, 0, ItemSize.Height, Height))
        End If
    End If


    'selected tab stuff
    Dim b2 As New SolidBrush(Color.FromArgb(44, 170, 250))
    For i = 0 To TabCount - 1
        If i = SelectedIndex Then
            Dim x2 As Rectangle = New Rectangle(GetTabRect(i).Location.X - 2, GetTabRect(i).Location.Y - 2, GetTabRect(i).Width, GetTabRect(i).Height + 4)
            Dim myblend1 As New ColorBlend()
            myblend1.Colors = {Color.FromArgb(44, 170, 250), Color.FromArgb(44, 170, 250), Color.FromArgb(44, 170, 250)} 'colors
            myblend1.Positions = {0.0F, 0.5F, 1.0F}
            Dim lgBrush1 As New LinearGradientBrush(x2, Color.Black, Color.Black, 90.0F)
            lgBrush1.InterpolationColors = myblend1
            G.FillRectangle(lgBrush1, x2)
            Dim tabTextArea As Rectangle = GetTabRect(i)
            e.Graphics.FillRectangle(b2, tabTextArea)
            Using br As New SolidBrush(Color.FromArgb(80, 80, 97))
    TextRenderer.DrawText(e.Graphics, TabPages(i).Text, New Font("Segoe UI light", 10.0), tabTextArea, TabPages(i).ForeColor)

            End Using
 If ImageList IsNot Nothing Then
                Try
                    If ImageList.Images(TabPages(i).ImageIndex) IsNot Nothing Then

                        G.DrawImage(ImageList.Images(TabPages(i).ImageIndex), New Point(x2.Location.X, x2.Location.Y))
                        G.DrawString("      " & TabPages(i).Text, Font, Me.ToBrush(Me.TextColor), x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                    Else
                        G.DrawString(TabPages(i).Text, New Font(Font.FontFamily, Font.Size, FontStyle.Regular), Me.ToBrush(Me.TextColor), x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                    End If
                Catch ex As Exception
                    G.DrawString(TabPages(i).Text, New Font(Font.FontFamily, Font.Size, FontStyle.Regular), Me.ToBrush(Me.TextColor), x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                End Try
            Else
                G.DrawString(TabPages(i).Text, New Font(Font.FontFamily, Font.Size, FontStyle.Regular), Me.ToBrush(Me.TextColor), x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
            End If

            If LightTheme = False Then
                G.DrawLine(New Pen(Color.FromArgb(80, 80, 97)), New Point(x2.Location.X - 2, x2.Location.Y - 1), New Point(x2.Location.X, x2.Location.Y))
                G.DrawLine(New Pen(Color.FromArgb(80, 80, 97)), New Point(x2.Location.X - 1, x2.Bottom - 1), New Point(x2.Location.X, x2.Bottom))
            Else
                G.DrawLine(New Pen(Color.FromArgb(80, 80, 97)), New Point(x2.Location.X - 2, x2.Location.Y - 11), New Point(x2.Location.X, x2.Location.Y))
                G.DrawLine(New Pen(Color.FromArgb(80, 80, 97)), New Point(x2.Location.X - 1, x2.Bottom - 1), New Point(x2.Location.X, x2.Bottom))
            End If

        Else
            Dim x1 As Rectangle = New Rectangle(GetTabRect(i).Location.X, GetTabRect(i).Location.Y, GetTabRect(i).Width, GetTabRect(i).Height )

   ' unselected tab color
            If LightTheme = False Then
                G.FillRectangle(New SolidBrush(Color.FromArgb(80, 80, 97)), x1)

            Else
                G.FillRectangle(New SolidBrush(Color.FromArgb(80, 80, 97)), x1)

            End If

     If LightTheme = False Then
                If ImageList IsNot Nothing Then
                    Try
                        If ImageList.Images(TabPages(i).ImageIndex) IsNot Nothing Then
                            G.DrawImage(ImageList.Images(TabPages(i).ImageIndex), New Point(x1.Location.X, x1.Location.Y))
                            G.DrawString("      " & TabPages(i).Text, Font, Brushes.Azure, x1, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                        Else
                            G.DrawString(TabPages(i).Text, Font, Brushes.Azure, x1, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                        End If
                    Catch ex As Exception
                        G.DrawString(TabPages(i).Text, Font, Brushes.Azure, x1, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                    End Try
                Else
                    G.DrawString(TabPages(i).Text, Font, Brushes.Azure, x1, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                End If
            ElseIf LightTheme = True Then
                If ImageList IsNot Nothing Then
                    Try
                        If ImageList.Images(TabPages(i).ImageIndex) IsNot Nothing Then
                            G.DrawImage(ImageList.Images(TabPages(i).ImageIndex), New Point(x1.Location.X, x1.Location.Y))
                            G.DrawString("      " & TabPages(i).Text, Font, ToBrush(Color.FromArgb(255, 64, 64, 64)), x1, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                        Else
                            G.DrawString(TabPages(i).Text, Font, ToBrush(Color.FromArgb(255, 64, 64, 64)), x1, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                        End If
                    Catch ex As Exception
                        G.DrawString(TabPages(i).Text, Font, ToBrush(Color.FromArgb(255, 64, 64, 64)), x1, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                    End Try
                Else
                    G.DrawString(TabPages(i).Text, Font, ToBrush(Color.FromArgb(255, 64, 64, 64)), x1, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                End If
                '................................................................................................

            End If
        End If
    Next

    e.Graphics.DrawImage(B.Clone, 0, 0)
    G.Dispose() : B.Dispose()

End Sub

End Class

What i want is, when i hover over an unselected tab,the tab header color would change like the built-in tabcontrol.Is it possible ?

A few more things i'ld like to know.I hope all of guys have used recent microsoft products like office 16,outlook 16 . The tabcontrol that these softwares contain some animations. I mean when u click on a tab(from the menubar), the color smoothly fades in unlike the tabcontrol i made where the color changes immidietly when i select the tab..Recently i have been working on WPF(XAML DESIGNING i mean) so i am preety much sure that i can achieve what i want(i mean the kinnda animation that Office/OutLook has) in WPF. But is Office/OutLook WPF applications ? Is there no way to achieve these animated looks in WinForms because creating the same TabControl i made in wpf would require a lot of XAML coding, maybe beyond my knowledge ..

Any Help ?

Visual Vincent
  • 18,045
  • 5
  • 28
  • 75
Software Dev
  • 5,368
  • 5
  • 22
  • 45
  • Is your code doing anything of what you want at the moment? Also, it appears to be incomplete, so won't compile, so we can't help debug. – Andrew Mortimer Dec 24 '17 at 07:07
  • please re-read the post – Software Dev Dec 24 '17 at 07:28
  • Why are you creating an image which you then draw to the control? That's a huge waste of processing power and memory... You should always use the `Graphics` object that is passed along with the `Paint` event directly. Change your `G` declaration to: `Dim G As Graphics = e.Graphics` and remove the bitmap altogether. – Visual Vincent Dec 24 '17 at 08:59
  • Also, please don't put tags and language names in the title. Stack Overflow's tag system ensures that users see questions that they're interested in if the question has the appropriate tags. Therefore it is completely unnecessary to put "VB.NET" in the title since those looking for VB.NET questions will find them based on the tags you've added. See this for more info: [Should questions include "tags" in their titles?](https://meta.stackexchange.com/a/130208) – Visual Vincent Dec 24 '17 at 09:04
  • @visual vincent,can u hlp me with the problem stated in the question? – Software Dev Dec 24 '17 at 09:15
  • Yes, I was working on this comment: As for your question, what you have to do is **1)** Override the `OnMouseMove` method and check if the mouse is currently over any tab. When you find that it is over a tab you store the tab's index in a class-level variable (let's call it `MouseOverTabIndex` for example) and call `Me.Invalidate()` to redraw your tab control. **2)** In the `OnPaint` method's loop you then just have to check `If i = MouseOverTabIndex` and draw that tab differently. **3)** Finally, when you find that the mouse is no longer located over a tab you set `MouseOverTabIndex = -1`. – Visual Vincent Dec 24 '17 at 09:20
  • Here's a C# answer (easily convertible to VB.NET) that'll help you check if the mouse is currently over a tab or not (ignore that they're changing the `SelectedIndex`): https://stackoverflow.com/a/9662219 – Visual Vincent Dec 24 '17 at 09:23
  • @VisualVincent,bro, need a suggestion, as i mentioned i want to achieve animated looks like Office/OutLook in my EMAIL app, so should i go with winforms or WPF ? – Software Dev Dec 25 '17 at 04:02
  • WPF is usually the best when it comes to animations. So far I've not been able to achieve any good results when trying to animate in WinForms. – Visual Vincent Dec 25 '17 at 10:26
  • @visual vincent,is outlook/office wpf application? – Software Dev Dec 25 '17 at 11:23
  • @visual vincent, can u chat with me please? i have a lot of things to learn regarding programming...please?? – Software Dev Dec 25 '17 at 11:28
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/161929/discussion-between-visual-vincent-and-zack-raiyan). – Visual Vincent Dec 25 '17 at 11:55

0 Answers0