Results 1 to 4 of 4

Thread: [05/08] TabControl with draggable tabs

  1. #1

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    [05/08] TabControl with draggable tabs

    Hi,

    Here is a TabControl that allows the user to change the order of the TabPages manually by Dragging and Dropping them somewhere else in the list.

    Credits to my source (C# code which I converted to VB.NET):
    http://www.codeproject.com/KB/tabs/d...abcontrol.aspx


    An example project is attached.

    The code for the usercontrol class can be found at the bottom.
    Note that if you want to recreate this control you need to take the following steps:
    1) Add a new UserControl
    2) Enable the 'Show All files' option by clicking the Show All files button in the Solution Explorer toolstrip (second button from the left).
    3) You will notice you can now expand the UserControl icon entry in the Solution Explorer: expand it and open the <UsercontrolName>.Designer.vb file.
    4) At the top, change the following to:
    Code:
    Inherits System.Windows.Forms.UserControl
    
    'Change to:
    Inherits System.Windows.Forms.TabControl
    5) Comment out any lines (in this file) that might give you an error (the Me.AutoScaleMode = ... line for example)
    6) Disable the Show All files button again and open the UserControl code. Paste my code in there.

    Code:
    Imports System.Collections.ObjectModel
    
    Public Class dragTabCtrl
    
        Public Sub New()
    
            ' This call is required by the Windows Form Designer.
            InitializeComponent()
    
            ' Add any initialization after the InitializeComponent() call.
            Me.AllowDrop = True
        End Sub
    
        '// Overrides the DragOver event
        Protected Overrides Sub OnDragOver(ByVal drgevent As System.Windows.Forms.DragEventArgs)
            MyBase.OnDragOver(drgevent)
    
            'Get the coords of our mouse in Client coordinates
            Dim pt As Point = PointToClient(New Point(drgevent.X, drgevent.Y))
    
            'Get the Tab
            Dim hoverTab As TabPage = GetTabPageFromPoint(pt)
    
            If hoverTab IsNot Nothing Then
    
                If drgevent.Data.GetDataPresent(GetType(TabPage)) Then
    
                    drgevent.Effect = DragDropEffects.Move
    
                    'Get the dragged tab
                    Dim dragTab As TabPage = DirectCast(drgevent.Data.GetData(GetType(TabPage)), TabPage)
    
                    'Get the tabindex of the dragged tab and the hovered tab
                    Dim dragIndex As Integer = FindIndex(dragTab)
                    Dim dropIndex As Integer = FindIndex(hoverTab)
    
                    'If they are the same we don't need to do anything
                    If dragIndex <> dropIndex Then
    
                        'Add each tabpage, except the dragged tab (!), to a new tabpage collection
                        Dim pages As New Collection(Of TabPage)
                        For i As Integer = 0 To Me.TabPages.Count - 1
    
                            If i <> dragIndex Then
                                pages.Add(Me.TabPages(i))
                            End If
    
                        Next
    
                        'We now have a collection of all our tabs except the dragged tab
                        'So insert the dragged tab at the appropriate index
                        pages.Insert(dropIndex, dragTab)
    
                        'Clear and re-add the pages
                        TabPages.Clear()
                        TabPages.AddRange(pages.ToArray())
    
                        'Select the dragged tab
                        Me.SelectedTab = dragTab
                    End If
    
                Else
                    drgevent.Effect = DragDropEffects.None
                End If
    
            End If
        End Sub
    
        Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
            MyBase.OnMouseDown(e)
    
            Dim pt As Point = New Point(e.X, e.Y)
            Dim tp As TabPage = GetTabPageFromPoint(pt)
    
            If tp IsNot Nothing Then
                DoDragDrop(tp, DragDropEffects.All)
            End If
        End Sub
    
        '// Returns the TabPage whose TabHeader is located at the point 'pt'
        Private Function GetTabPageFromPoint(ByVal pt As Point) As TabPage
            Dim tp As TabPage = Nothing
    
            For i As Integer = 0 To Me.TabPages.Count - 1
                If Me.GetTabRect(i).Contains(pt) Then
                    tp = Me.TabPages(i)
                    Exit For
                End If
            Next
    
            Return tp
        End Function
    
        '// Returns the index of the TabPage
        Private Function FindIndex(ByVal page As TabPage) As Integer
            Dim rslt As Integer = -1
            For i As Integer = 0 To Me.TabPages.Count - 1
                If Me.TabPages(i) Is page Then
                    rslt = i
                    Exit For
                End If
            Next
            Return rslt
        End Function
    
    End Class
    Attached Files Attached Files

  2. #2
    Member Reva's Avatar
    Join Date
    Sep 2008
    Posts
    60

    Re: [05/08] TabControl with draggable tabs

    is there any better solution,

    i'm fast reading these code, and this way by create new collection of Tab. does it memory eating?

  3. #3

    Thread Starter
    PowerPoster
    Join Date
    Apr 2007
    Location
    The Netherlands
    Posts
    5,070

    Re: [05/08] TabControl with draggable tabs

    As far as I know you cannot get around creating a collection or list or array that holds the tabs.

    I tested this code with up to 25-30 (empty) tabs and I did not notice any lag or slowdown at all. Maybe it is a different story with controls on the tabs, but in my opinion any design using more than about 10 tabs on a single form needs serious reconsideration...

    Did you try the code, was it slow for you?

  4. #4
    Member Reva's Avatar
    Join Date
    Sep 2008
    Posts
    60

    Re: [05/08] TabControl with draggable tabs

    the code doesn't slow, but by using this technique makes the pages of tabpages flicking.

    when i'm search the code, i also find some ref by jmcilhilney
    here

    http://www.vbforums.com/showthread.p...hlight=Tabpage

    that the "tab" of TabControl is belongs to the tabcontrol not the collection of tabpages.

    so i think when we drag the tab, i mean to drag the tab not the pages.

    your technique is a tricky solution, however this not going to be considered if u have not much tabpages and the control inside the tab isn't much.

    but consider if each tabpage is containing a control that make a data connection and populating data such as a database or maybe a webpage.

    i'm looking about "ownerdraw the tab" maybe this could solve the issue. but i haven't try to make it.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width