locked
Tabcontrol add buttons like "Add" and "Close" RRS feed

  • Question

  • Hey there.

    Can somebody explain to me how to add some buttons to the tabcontrol?

    I want to have a "X" on the tab itself. And a "+" behind the tab to create a new one.

    And when a new one is created it moves further.

    I've searched all over the internet couldn't find anything about the add button.

    Please help me

    Thursday, July 14, 2011 9:24 AM

Answers

  • Creating a Custom TabControl and/or TabPage and creating custom drawing code is definately one way to handle this requirement; and perhaps the best way, but that depends on your needs.

    Depending on how you will ultimately use this TabControl, you may be able to simply configure a normal TabControl to behave close enough to what you describe.  This would be quicker and much easier than creating a customized TabControl, but it will not allow as much customization so you may not be able to achieve exactly what you envisioned (but though it may look a little different than you had in mind, it should still function as you require).

    Please consider the following code example (pasted into a new, blank Form1):

    Public Class Form1
      Private WithEvents _MainTabControl As New TabControl
      Private _NewPageTab As New TabPage
    
      Private _TabAddedFlag As Boolean
    
      Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        _MainTabControl.Dock = DockStyle.Fill
        _MainTabControl.ImageList = New ImageList
        _MainTabControl.ImageList.ImageSize = New Size(16, 16)
        _MainTabControl.ImageList.Images.Add(SystemIcons.Error.ToBitmap)
        _MainTabControl.TabPages.Add(String.Empty, "Page1", 0)
        Controls.Add(_MainTabControl)
    
        _NewPageTab.Name = "NewPageTab"
        _NewPageTab.Text = "(New)"
        _MainTabControl.TabPages.Add(_NewPageTab)
      End Sub
    
      Private Sub _MainTabControl_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles _MainTabControl.MouseUp
        If Not _TabAddedFlag AndAlso Not _MainTabControl.SelectedTab Is _NewPageTab Then
          Dim clickPoint As Point = PointToClient(MousePosition)
          Dim buttonBounds As Rectangle = _MainTabControl.GetTabRect(_MainTabControl.SelectedIndex)
          buttonBounds.Width = _MainTabControl.ImageList.ImageSize.Width
    
          If buttonBounds.Contains(clickPoint) Then
            _MainTabControl.TabPages.Remove(_MainTabControl.SelectedTab)
          End If
        End If
        _TabAddedFlag = False
      End Sub
    
      Private Sub _MainTabControl_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles _MainTabControl.SelectedIndexChanged
        If _MainTabControl.SelectedTab Is _NewPageTab Then
          Dim count As Integer = _MainTabControl.TabPages.Count
          Dim newPage As New TabPage("Page " & count.ToString)
          newPage.ImageIndex = 0
          _MainTabControl.TabPages.Insert(count - 1, newPage)
          _MainTabControl.SelectedTab = newPage
          _TabAddedFlag = True
        End If
      End Sub
    End Class
    


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"
    • Marked as answer by markieo Sunday, July 17, 2011 8:23 AM
    Saturday, July 16, 2011 7:14 PM
    Moderator

All replies

  • You have to inherit the TabControl and Override some methods to do this
    Muthu Krishnan.R Use only what you need, Reduce global warming
    Thursday, July 14, 2011 7:05 PM
  • Hey there.

    Can somebody explain to me how to add some buttons to the tabcontrol?

    I want to have a "X" on the tab itself. And a "+" behind the tab to create a new one.

    And when a new one is created it moves further.

    I've searched all over the internet couldn't find anything about the add button.

    Please help me

    Hi markieo,

    Here is an alternative suggestion.

    Run this code and right-click on the TabPage.

    You will have 3 options;

    • Add TabPage
    • Delete current TabPage
    • Renumber all TabPages

     

    I hope you find this useful?

     

    Option Strict On
    Option Explicit On
    Option Infer Off
    
    Public Class Form1
    
      Friend WithEvents tc As New TabControl
      Friend WithEvents cm As New ContextMenu
      Friend WithEvents menuItem1 As New MenuItem("Add TabPage")
      Friend WithEvents menuItem2 As New MenuItem("Delete current TabPage")
      Friend WithEvents menuItem3 As New MenuItem("Renumber all TabPages")
    
      Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
        Me.WindowState = FormWindowState.Maximized
        tc.Dock = DockStyle.Fill
        Me.Controls.Add(tc)
    
        Dim menuItems() As MenuItem = New MenuItem() {menuItem1, menuItem2, menuItem3}
    
        cm = New ContextMenu(menuItems)
        tc.ContextMenu = cm
    
        Dim tp As New TabPage
        tp.Text = "TabPage1"
        tp.Name = "TabPage1"
        tc.TabPages.Add(tp)
    
      End Sub
    
      Private tabNumber As Integer = 2
    
      Private Sub menuItem1_Select(ByVal sender As Object, ByVal e As System.EventArgs) Handles menuItem1.Select
    
        Dim newTabPage As New TabPage
        With newTabPage
          .Text = "TabPage" & tabNumber.ToString
          .Name = "TabPage" & tabNumber.ToString
        End With
        tc.TabPages.Add(newTabPage)
        tabNumber += 1
    
      End Sub
    
      Private Sub menuItem2_Select(ByVal sender As Object, ByVal e As System.EventArgs) Handles menuItem2.Select
    
        If tc.TabPages.Count > 1 Then
          tc.TabPages.Remove(tc.SelectedTab)
        End If
    
      End Sub
    
      Private Sub menuItem3_Select(ByVal sender As Object, ByVal e As System.EventArgs) Handles menuItem3.Select
    
        For index As Integer = 1 To tc.TabPages.Count
          With tc.TabPages.Item(index - 1)
            .Text = "TabPage" & index.ToString
            .Name = "TabPage" & index.ToString
          End With
        Next
    
      End Sub
    
    End Class
    




    Regards,

    John

    Click this link to see how to insert a picture into a forum post.

    Installing VB6 on Windows 7

    XNA is coming to VB.Net

    App Hub forums



    Thursday, July 14, 2011 9:59 PM
  • what you're asking for is an ownerdrawn tabcontrol. here's some more information:

     

    http://dotnetrix.co.uk/tabcontrol.htm


    thanks for any help
    Friday, July 15, 2011 12:00 AM
  • Hey there.

    Can somebody explain to me how to add some buttons to the tabcontrol?

    I want to have a "X" on the tab itself. And a "+" behind the tab to create a new one.

    And when a new one is created it moves further.

    I've searched all over the internet couldn't find anything about the add button.

    Please help me

    Hi markieo,

    Here is an alternative suggestion.

    Run this code and right-click on the TabPage.

    You will have 3 options;

    • Add TabPage
    • Delete current TabPage
    • Renumber all TabPages

     

    I hope you find this useful?

     

     

    Option Strict On
    Option Explicit On
    Option Infer Off
    
    Public Class Form1
    
     Friend WithEvents tc As New TabControl
     Friend WithEvents cm As New ContextMenu
     Friend WithEvents menuItem1 As New MenuItem("Add TabPage")
     Friend WithEvents menuItem2 As New MenuItem("Delete current TabPage")
     Friend WithEvents menuItem3 As New MenuItem("Renumber all TabPages")
    
     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
      Me.WindowState = FormWindowState.Maximized
      tc.Dock = DockStyle.Fill
      Me.Controls.Add(tc)
    
      Dim menuItems() As MenuItem = New MenuItem() {menuItem1, menuItem2, menuItem3}
    
      cm = New ContextMenu(menuItems)
      tc.ContextMenu = cm
    
      Dim tp As New TabPage
      tp.Text = "TabPage1"
      tp.Name = "TabPage1"
      tc.TabPages.Add(tp)
    
     End Sub
    
     Private tabNumber As Integer = 2
    
     Private Sub menuItem1_Select(ByVal sender As Object, ByVal e As System.EventArgs) Handles menuItem1.Select
    
      Dim newTabPage As New TabPage
      With newTabPage
       .Text = "TabPage" & tabNumber.ToString
       .Name = "TabPage" & tabNumber.ToString
      End With
      tc.TabPages.Add(newTabPage)
      tabNumber += 1
    
     End Sub
    
     Private Sub menuItem2_Select(ByVal sender As Object, ByVal e As System.EventArgs) Handles menuItem2.Select
    
      If tc.TabPages.Count > 1 Then
       tc.TabPages.Remove(tc.SelectedTab)
      End If
    
     End Sub
    
     Private Sub menuItem3_Select(ByVal sender As Object, ByVal e As System.EventArgs) Handles menuItem3.Select
    
      For index As Integer = 1 To tc.TabPages.Count
       With tc.TabPages.Item(index - 1)
        .Text = "TabPage" & index.ToString
        .Name = "TabPage" & index.ToString
       End With
      Next
    
     End Sub
    
    End Class
    


     



    Regards,

    John

    Click this link to see how to insert a picture into a forum post.

    Installing VB6 on Windows 7

    XNA is coming to VB.Net

    App Hub forums



    I don't want that. I want a button behind the tab and one on the tab for closing.

    Like firefox has.

    And Paul i dont understand how to add the button to it :(

    Friday, July 15, 2011 8:25 AM
  • Can somebody help me??
    Saturday, July 16, 2011 1:49 PM
  • Creating a Custom TabControl and/or TabPage and creating custom drawing code is definately one way to handle this requirement; and perhaps the best way, but that depends on your needs.

    Depending on how you will ultimately use this TabControl, you may be able to simply configure a normal TabControl to behave close enough to what you describe.  This would be quicker and much easier than creating a customized TabControl, but it will not allow as much customization so you may not be able to achieve exactly what you envisioned (but though it may look a little different than you had in mind, it should still function as you require).

    Please consider the following code example (pasted into a new, blank Form1):

    Public Class Form1
      Private WithEvents _MainTabControl As New TabControl
      Private _NewPageTab As New TabPage
    
      Private _TabAddedFlag As Boolean
    
      Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        _MainTabControl.Dock = DockStyle.Fill
        _MainTabControl.ImageList = New ImageList
        _MainTabControl.ImageList.ImageSize = New Size(16, 16)
        _MainTabControl.ImageList.Images.Add(SystemIcons.Error.ToBitmap)
        _MainTabControl.TabPages.Add(String.Empty, "Page1", 0)
        Controls.Add(_MainTabControl)
    
        _NewPageTab.Name = "NewPageTab"
        _NewPageTab.Text = "(New)"
        _MainTabControl.TabPages.Add(_NewPageTab)
      End Sub
    
      Private Sub _MainTabControl_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles _MainTabControl.MouseUp
        If Not _TabAddedFlag AndAlso Not _MainTabControl.SelectedTab Is _NewPageTab Then
          Dim clickPoint As Point = PointToClient(MousePosition)
          Dim buttonBounds As Rectangle = _MainTabControl.GetTabRect(_MainTabControl.SelectedIndex)
          buttonBounds.Width = _MainTabControl.ImageList.ImageSize.Width
    
          If buttonBounds.Contains(clickPoint) Then
            _MainTabControl.TabPages.Remove(_MainTabControl.SelectedTab)
          End If
        End If
        _TabAddedFlag = False
      End Sub
    
      Private Sub _MainTabControl_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles _MainTabControl.SelectedIndexChanged
        If _MainTabControl.SelectedTab Is _NewPageTab Then
          Dim count As Integer = _MainTabControl.TabPages.Count
          Dim newPage As New TabPage("Page " & count.ToString)
          newPage.ImageIndex = 0
          _MainTabControl.TabPages.Insert(count - 1, newPage)
          _MainTabControl.SelectedTab = newPage
          _TabAddedFlag = True
        End If
      End Sub
    End Class
    


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"
    • Marked as answer by markieo Sunday, July 17, 2011 8:23 AM
    Saturday, July 16, 2011 7:14 PM
    Moderator
  • Thanks that is what i needed !!
    Sunday, July 17, 2011 8:23 AM
  • Hi Reed Kimble,

    Nice code however try this, add 4 pages then remove Page3, then add a new page.

    You have now have two pages labelled "Page4"  :-(

     

    Suggestion, if I may, add 1 to the number of the highest numbered existing TabPage /

    simply renumber all of the TabPages when one is removed.

     

    Here is the Renumber idea added to your code.>>

     

    Public Class Form1
    
      Private WithEvents _MainTabControl As New TabControl
      Private _NewPageTab As New TabPage
      Private _TabAddedFlag As Boolean
    
      Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        _MainTabControl.Dock = DockStyle.Fill
        _MainTabControl.ImageList = New ImageList
        _MainTabControl.ImageList.ImageSize = New Size(16, 16)
        _MainTabControl.ImageList.Images.Add(SystemIcons.Error.ToBitmap)
        _MainTabControl.TabPages.Add(String.Empty, "Page1", 0)
        Controls.Add(_MainTabControl)
    
        _NewPageTab.Name = "NewPageTab"
        _NewPageTab.Text = "(New)"
        _MainTabControl.TabPages.Add(_NewPageTab)
      End Sub
    
      Private Sub _MainTabControl_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles _MainTabControl.MouseUp
    
        If Not _TabAddedFlag AndAlso Not _MainTabControl.SelectedTab Is _NewPageTab Then
          Dim clickPoint As Point = PointToClient(MousePosition)
          Dim buttonBounds As Rectangle = _MainTabControl.GetTabRect(_MainTabControl.SelectedIndex)
          buttonBounds.Width = _MainTabControl.ImageList.ImageSize.Width
    
          If buttonBounds.Contains(clickPoint) Then
            _MainTabControl.TabPages.Remove(_MainTabControl.SelectedTab)
            RenumberTabPages()
          End If
        End If
        _TabAddedFlag = False
    
      End Sub
    
      Private Sub _MainTabControl_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles _MainTabControl.SelectedIndexChanged
    
        If _MainTabControl.SelectedTab Is _NewPageTab Then
          Dim count As Integer = _MainTabControl.TabPages.Count
          Dim newPage As New TabPage("Page " & count.ToString)
          newPage.ImageIndex = 0
          _MainTabControl.TabPages.Insert(count - 1, newPage)
          _MainTabControl.SelectedTab = newPage
          _TabAddedFlag = True
        End If
    
      End Sub
    
      Private Sub RenumberTabPages()
    
        For index As Integer = 0 To _MainTabControl.TabPages.Count - 2
          _MainTabControl.TabPages.Item(index).Text = "Page" & (index + 1).ToString
        Next
        _MainTabControl.TabPages.Item(_MainTabControl.TabPages.Count - 1).Text = "(New)"
    
      End Sub
    
    End Class




    Regards,

    John

    Click this link to see how to insert a picture into a forum post.

    Installing VB6 on Windows 7

    XNA is coming to VB.Net

    App Hub forums



    Sunday, July 17, 2011 10:45 AM
  • Hi John,

    LOL, yeah I'm well aware of the tab "naming" problem... but the code sample was about adding and removing tabs, not naming them.  =P

    There was a great article in MSDN Magazine a while back about writing API documentation and in it there was a section about sample code that is really applicable to any samples (not just in documentation).  The important part is that sample code should clearly demonstrate a particular idea or concept and does not necessairly need to be written most efficiently, especially in areas that are suplemental to the idea or concept being demonstrated.  Clarity > Efficiency in sample code. :)

    Still though, its a good addition to the thread in case someone gets stuck at that point.  Thanks for sharing!

     

    PS

    I found a link to that article if you are interested:

    http://msdn.microsoft.com/en-us/magazine/gg309172.aspx


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"
    Sunday, July 17, 2011 6:33 PM
    Moderator
  • Still though, its a good addition to the thread in case someone gets stuck at that point.  Thanks for sharing!

     

    PS

    I found a link to that article if you are interested:

    http://msdn.microsoft.com/en-us/magazine/gg309172.aspx


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Hi Reed,

    Your welcome and thanks for the link.  :-)    :)    :-D    ;-)

    I was thinking showing your code wrapped up in code as a UserControl too.



    Regards,

    John

    Click this link to see how to insert a picture into a forum post.

    Installing VB6 on Windows 7

    XNA is coming to VB.Net

    App Hub forums



    Sunday, July 17, 2011 10:29 PM
  • Monday, July 18, 2011 12:36 AM
  • Hi again Reed Kimble,

     

    I've been trying like a man possessed to get your above code to work in a different fashion.

    With code from this thread:>>

    http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/20d8ceb6-e5e4-4e20-bd68-70c74b047f94

    to prevent TabPages that have "TabPage" in their name being added.

     

    Combining in my code from here:>>

    http://social.msdn.microsoft.com/Forums/en-US/vbgeneral/thread/5b34dfdb-f59d-49b0-87de-48cfe9be43de

    but I Inherit from TabControl instead.

     

    The functionality of the code below works in DESIGN MODE with a slight quirk,

    sometimes you have to select a TabPage before you can click on (New).

     

    But not when you run the code, can you see what is wrong at all please?

    It seems like the designer / FrameWork is still trying to add 2 TabPages named "TabPage1" and "TabPage2" or whatever.

     

    Here is what I have so far...

    Public Class NewerTabControl
      Inherits System.Windows.Forms.TabControl
    
      Private Sub MyTabControl_ControlAdded(ByVal sender As Object, ByVal e As System.Windows.Forms.ControlEventArgs) Handles Me.ControlAdded
    
        'Loop which removes ALL default Tabpages.
        'Note if you do not do it this way and just remove
        ' "TabPage1" and "TabPage2" the designer will add "TabPage3" and "Tabpage4"
        ' or some other numbered "TabPages"
        For Each tp As TabPage In Me.TabPages
          If tp.Name.Contains("TabPage") Then
            Me.TabPages.Remove(tp)
          End If
        Next
    
      End Sub
    
      Private newPageTab As New TabPage
      Private tabAddedFlag As Boolean
    
      Private Sub New()
    
        Me.Size = New Size(300, 200)
        Me.ImageList = New ImageList
        Me.ImageList.ImageSize = New Size(16, 16)
        Me.ImageList.Images.Add(SystemIcons.Error.ToBitmap)
        Me.TabPages.Add(String.Empty, "Page1", 0)
        Me.TabPages.Item(0).Name = "Page1"
        newPageTab.Name = "NewPageTab"
        newPageTab.Text = "(New)"
        Me.TabPages.Add(newPageTab)
    
      End Sub
    
      Private Sub Me_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles Me.MouseUp
    
        If Not tabAddedFlag AndAlso Not Me.SelectedTab Is newPageTab Then
          Dim clickPoint As Point = PointToClient(MousePosition)
          Dim buttonBounds As Rectangle = Me.GetTabRect(Me.SelectedIndex)
          buttonBounds.Width = Me.ImageList.ImageSize.Width
    
          If buttonBounds.Contains(clickPoint) Then
            Me.TabPages.Remove(Me.SelectedTab)
            RenumberTabPages()
          End If
        End If
        tabAddedFlag = False
    
      End Sub
    
      Private Sub Me_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.SelectedIndexChanged
    
        If Me.SelectedTab Is newPageTab Then
          Dim count As Integer = Me.TabPages.Count
          Dim newPage As New TabPage("Page" & count.ToString)
    
          'Each page will get a unique Name ( hopefully ),
          'regardless of whether TabPages are added or deleted.>>
          Static pageNumber As Integer = count
          newPage.Name = ("Page" & pageNumber.ToString)
          pageNumber += 1
    
          newPage.ImageIndex = 0
          Me.TabPages.Insert(count - 1, newPage)
          Me.SelectedTab = newPage
          tabAddedFlag = True
        End If
    
      End Sub
    
      Private Sub RenumberTabPages()
    
        For index As Integer = 0 To Me.TabPages.Count - 2
          Me.TabPages.Item(index).Text = "Page" & (index + 1).ToString
        Next
        Me.TabPages.Item(Me.TabPages.Count - 1).Text = "(New)"
        Me.TabPages.Item(Me.TabPages.Count - 1).Name = "NewPageTab"
    
      End Sub
    End Class
    




    Regards,

    John

    Click this link to see how to insert a picture into a forum post.

    Installing VB6 on Windows 7

    XNA is coming to VB.Net

    App Hub forums



    Thursday, July 21, 2011 8:05 PM