# VBForums CodeBank > CodeBank - Visual Basic .NET >  TabControl with Close button on TabPages (with Design-Time support)

## Pradeep1210

This article shows how to add a close button to the tabs on your TabControl.

*Usage:*
1. Add a new class to your application (preferably named TabControlEx.vb)
2. Copy and paste this code into that class.
3. Rebuild.
4. Now you should see a new item in the Control Toolbox named TabControlEx. Drag this control to your form.

*Features:*
1. The _ShowCloseButtonOnTabs_ property controls whether close button is shown on the tabs on not. By default this is True.
2. The _CloseButtonClick_ event is raised when any of the close buttons is clicked. By default this closes the tab, but you can set the e.Cancel = True inside this event handler to prevent closing the tab.


vb.net Code:
Option Strict OnImports System.ComponentModel <ToolboxBitmap(GetType(System.Windows.Forms.TabControl))> _Public Class TabControlEx    Inherits TabControl     Private Declare Auto Function SetParent Lib "user32" (ByVal hWndChild As IntPtr, ByVal hWndNewParent As IntPtr) As IntPtr    Protected CloseButtonCollection As New Dictionary(Of Button, TabPage)    Private _ShowCloseButtonOnTabs As Boolean = True     <Browsable(True), DefaultValue(True), Category("Behavior"), Description("Indicates whether a close button should be shown on each TabPage")> _    Public Property ShowCloseButtonOnTabs() As Boolean        Get            Return _ShowCloseButtonOnTabs        End Get        Set(ByVal value As Boolean)            _ShowCloseButtonOnTabs = value            For Each btn In CloseButtonCollection.Keys                btn.Visible = _ShowCloseButtonOnTabs            Next            RePositionCloseButtons()        End Set    End Property     Protected Overrides Sub OnCreateControl()        MyBase.OnCreateControl()        RePositionCloseButtons()    End Sub     Protected Overrides Sub OnControlAdded(ByVal e As System.Windows.Forms.ControlEventArgs)        MyBase.OnControlAdded(e)        Dim tp As TabPage = DirectCast(e.Control, TabPage)        Dim rect As Rectangle = Me.GetTabRect(Me.TabPages.IndexOf(tp))        Dim btn As Button = AddCloseButton(tp)        btn.Size = New Size(rect.Height - 1, rect.Height - 1)        btn.Location = New Point(rect.X + rect.Width - rect.Height - 1, rect.Y + 1)        SetParent(btn.Handle, Me.Handle)        AddHandler btn.Click, AddressOf OnCloseButtonClick        CloseButtonCollection.Add(btn, tp)    End Sub     Protected Overrides Sub OnControlRemoved(ByVal e As System.Windows.Forms.ControlEventArgs)        Dim btn As Button = CloseButtonOfTabPage(DirectCast(e.Control, TabPage))        RemoveHandler btn.Click, AddressOf OnCloseButtonClick        CloseButtonCollection.Remove(btn)        SetParent(btn.Handle, Nothing)        btn.Dispose()        MyBase.OnControlRemoved(e)    End Sub     Protected Overrides Sub OnLayout(ByVal levent As System.Windows.Forms.LayoutEventArgs)        MyBase.OnLayout(levent)        RePositionCloseButtons()    End Sub     Public Event CloseButtonClick As CancelEventHandler    Protected Overridable Sub OnCloseButtonClick(ByVal sender As Object, ByVal e As EventArgs)        If Not DesignMode Then            Dim btn As Button = DirectCast(sender, Button)            Dim tp As TabPage = CloseButtonCollection(btn)            Dim ee As New CancelEventArgs            RaiseEvent CloseButtonClick(sender, ee)            If Not ee.Cancel Then                Me.TabPages.Remove(tp)                RePositionCloseButtons()            End If        End If    End Sub     Protected Overridable Function AddCloseButton(ByVal tp As TabPage) As Button        Dim closeButton As New Button        With closeButton            '' TODO: Give a good visual appearance to the Close button, maybe by assigning images etc.            ''       Here I have not used images to keep things simple.            .Text = "X"            .FlatStyle = FlatStyle.Flat            .BackColor = Color.FromKnownColor(KnownColor.ButtonFace)            .ForeColor = Color.White            .Font = New Font("Microsoft Sans Serif", 6, FontStyle.Bold)        End With        Return closeButton    End Function     Public Sub RePositionCloseButtons()        For Each item In CloseButtonCollection            RePositionCloseButtons(item.Value)        Next    End Sub     Public Sub RePositionCloseButtons(ByVal tp As TabPage)        Dim btn As Button = CloseButtonOfTabPage(tp)        If btn IsNot Nothing Then            Dim tpIndex As Integer = Me.TabPages.IndexOf(tp)            If tpIndex >= 0 Then                Dim rect As Rectangle = Me.GetTabRect(tpIndex)                If Me.SelectedTab Is tp Then                    btn.BackColor = Color.Red                    btn.Size = New Size(rect.Height - 1, rect.Height - 1)                    btn.Location = New Point(rect.X + rect.Width - rect.Height, rect.Y + 1)                Else                    btn.BackColor = Color.FromKnownColor(KnownColor.ButtonFace)                    btn.Size = New Size(rect.Height - 3, rect.Height - 3)                    btn.Location = New Point(rect.X + rect.Width - rect.Height - 1, rect.Y + 1)                End If                btn.Visible = ShowCloseButtonOnTabs                btn.BringToFront()            End If        End If    End Sub     Protected Function CloseButtonOfTabPage(ByVal tp As TabPage) As Button        Return (From item In CloseButtonCollection Where item.Value Is tp Select item.Key).FirstOrDefault    End FunctionEnd Class

----------


## NickThissen

This is pretty good! I've wanted to do this for a while but I've never thought of doing it like this, I've always thought the only way would be to custom draw the tab headers, in which case it is impossible (I think) to have them automatically assume the system theme.

The only down-side to this approach is that the buttons are created on top of the text in the tabpage header (at least if they are set to auto-size). I don't suppose it's possible to make every tabpage header a few pixels wider, while still maintaining the auto-size ability?

----------


## Pradeep1210

> This is pretty good! I've wanted to do this for a while but I've never thought of doing it like this, I've always thought the only way would be to custom draw the tab headers, in which case it is impossible (I think) to have them automatically assume the system theme.


Thanks  :Big Grin:   :Thumb: 




> The only down-side to this approach is that the buttons are created on top of the text in the tabpage header (at least if they are set to auto-size). I don't suppose it's possible to make every tabpage header a few pixels wider, while still maintaining the auto-size ability?


I never thought in these terms. I'll give it a try and let you know if I get to something.

----------


## reconrey

its good...but the button looks like doodoo...  :Smilie:

----------


## Pradeep1210

> its good...but the button looks like doodoo...


You can modify the *AddCloseButton* procedure to give whatever look you want for the button. 
What I showed in the demo is just a simple button with red background color. But you can use graphical images etc. to give it a better look.

----------


## minitech

Wow... so simple! It's great. Too bad you can't change the style of the tabs like this, though...

----------


## nbrege

What this control needs is a "+" at the end, that when clicked adds a new tabpage to the control, like most browsers have, but the "+" tab wouldn't have a close button on it. 
Also, how do you add a new tabpage to this control programatically?  Thanks...

----------


## minitech

Just use a button for the "+", not a tab. The code would be easy enough to modify - 10 pixels to the right of the last X button, add a + button.

----------


## samneric

Buttons overwrite text?

Try this....



```
    Protected Overrides Sub OnCreateControl()

        MyBase.OnCreateControl()

        For Each item In CloseButtonCollection

            item.Value.Text = item.Value.Text.Trim & Space(4)

        Next


        RePositionCloseButtons()

    End Sub
```

Steve

----------


## samneric

Or just put the item.value statement in the proc 'RePositionCloseButtons' (changing 'item.value' to 'tabpage' of course!)








> Buttons overwrite text?
> 
> Try this....
> 
> 
> 
> ```
>     Protected Overrides Sub OnCreateControl()
> 
> ...

----------


## lecfox

how do u rebuild?

----------


## prakash_dhimmer

you are really helping other. and one more thing your are very inteligent with helping nature. please continue to help us. 

One more time.

THANK YOU...









> This article shows how to add a close button to the tabs on your TabControl.
> 
> *Usage:*
> 1. Add a new class to your application (preferably named TabControlEx.vb)
> 2. Copy and paste this code into that class.
> 3. Rebuild.
> 4. Now you should see a new item in the Control Toolbox named TabControlEx. Drag this control to your form.
> 
> *Features:*
> ...

----------


## DejMan

I've found this article, how to add close button to tab headers in TabControl is explained in details.

----------


## carlbons

Thank you very much sir for this effort you gave to us! I really appreciate your kindness. I hope you will continue to share your knowledge to the needy  :Smilie: . 

Anyways guys! I have managed to edit some codes to change the appearance of the close button. Please see in the screenshot  :Smilie:

----------


## carlbons

Very nice

----------


## mkschoenrock

Wondering:  I am adding a tab named "ADDTAB" with a text value of "+" to be displayed.  I would like to NOT have a close button on this tab.  So, where in this class would I put something like... if  thistabpage.name = "ADDTAB" then do not add closebutton.  .. I've been trying for a bit and cant seem to get it... Thanks for any help...

----------


## linus2000

> Just use a button for the "+", not a tab. The code would be easy enough to modify - 10 pixels to the right of the last X button, add a + button.


Can someone tell me how i can do this?

----------


## 9kematian

> Wondering:  I am adding a tab named "ADDTAB" with a text value of "+" to be displayed.  I would like to NOT have a close button on this tab.  So, where in this class would I put something like... if  thistabpage.name = "ADDTAB" then do not add closebutton.  .. I've been trying for a bit and cant seem to get it... Thanks for any help...


it worked for me..  :Wink: 



```
Protected Overrides Sub OnControlAdded(ByVal e As System.Windows.Forms.ControlEventArgs)
        MyBase.OnControlAdded(e)
        Dim tp As TabPage = DirectCast(e.Control, TabPage)

        If tp.Text = "+" Then Exit Sub ' add close buttons <--------

        Dim rect As Rectangle = Me.GetTabRect(Me.TabPages.IndexOf(tp))
        Dim btn As Button = AddCloseButton(tp)
        btn.Size = New Size(rect.Height - 1, rect.Height - 1)
        btn.Location = New Point(rect.X + rect.Width - rect.Height - 1, rect.Y + 1)
        SetParent(btn.Handle, Me.Handle)
        AddHandler btn.Click, AddressOf OnCloseButtonClick
        CloseButtonCollection.Add(btn, tp)

'for dynamic created tab <--------
        For Each item In CloseButtonCollection
            item.Value.Text = item.Value.Text.Trim & Space(8)
        Next
        RePositionCloseButtons()
    End Sub
```

----------


## Absolute_Zero

@*Pradeep1210* Thank you!

I have a problem with TabControlEx, when set *Multiline* property to True or change *Appearance*, all close buttons disappear, i tried to call the method *RePositionCloseButtons* after changing these properties but it didn't work! 

Please help...

----------

