1 Attachment(s)
[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
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?
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?
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.