Solved

Movable Tabs on Tabcontrol

Posted on 2014-11-03
4
120 Views
Last Modified: 2014-12-19
Visual Studio 2013 VB.NET

I have a tab control on a windows form (vb.net) that i would like to allow users to change the order by dragging. Is this possible?
0
Comment
Question by:mickeyshelley1
  • 2
4 Comments
 
LVL 40
ID: 40420829
The TabPage the necessary method (DoDragDrop) and events (DragDrop), so it is possible.

Unfortunately, I do not have any code to show you. I never did it, and it can involve quite a few lines.

Look at the documentation for the DoDragDrop method, that shows the whole thing on both sides (start the drag and control the drop) between 2 ListBoxes. You would need something similar to insert a TabPage between 2 other TabPages.
0
 
LVL 33

Accepted Solution

by:
Mike Eghtebas earned 500 total points
ID: 40420846
tabs
I made this tab control, with two tabs. Then with mouse down, I dragged left or right. and then I let it go:

 mouse down used to capture the initial x value using:
Public Class Form1

    Dim Xinitial As Int32
    Dim Xfinal As Int32

    Private Sub TabPage2_MouseClick(sender As Object, e As MouseEventArgs) Handles TabPage2.MouseClick
        Xinitial = e.X
    End Sub

let it go helped to find final value of x:
    Private Sub TabPage2_MouseUp(sender As Object, e As MouseEventArgs) Handles TabPage2.MouseUp
        Xfinal = e.X

       'determined the user dragged to left or right:
        If Xfinal > Xfinal Then
            changeTabIndex("TabPage2", 1) ' to the right
        Else
            changeTabIndex("TabPage2", -1) ' to the left
        End If

    End Sub

This function could be further developed to re-index the refresh the form to rearrange the tabs:
    Private Sub changeTabIndex(TabName As String, intVal As Int32)
        Dim intNewIndex As Int32

       ' intNewIndex = TabControl1.SelectedIndex + intVal

        'TabControl1.SelectedIndex = intNewIndex

    End Sub

End Class

This is what I have done so far. I stopped to search if there is easier way of doing this so I don't have to re-invent the wheel.

Please the mouse-down and up on the tab area will respond to these events. They will not respond to if you work on tab on the top row.
0
 
LVL 27

Expert Comment

by:Ark
ID: 40420974
Public Class DraggableTabControl
    Inherits TabControl

    Private _srcPage As TabPage

    Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
        If (e.Button = MouseButtons.Left) AndAlso (SelectedTab IsNot Nothing) AndAlso (Not GetTabRect(SelectedIndex).IsEmpty) Then
            _srcPage = SelectedTab
        End If
        MyBase.OnMouseDown(e)
    End Sub

    Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)
        If (e.Button = MouseButtons.Left) AndAlso (_srcPage IsNot Nothing) Then
            Me.Cursor = If(TabPageFromPoint(e.Location) Is Nothing, Cursors.No, Cursors.VSplit)
        Else
            Me.Cursor = Cursors.Default
        End If
        MyBase.OnMouseMove(e)
    End Sub

    Protected Overrides Sub OnMouseUp(ByVal e As MouseEventArgs)
        SwapPages(_srcPage, TabPageFromPoint(e.Location))
        Me.SelectedTab = _srcPage
        _srcPage = Nothing
        MyBase.Cursor = Cursors.Default
        MyBase.OnMouseUp(e)
    End Sub

    Private Function TabPageFromPoint(ByVal pt As Point) As TabPage
        For i As Integer = 0 To TabPages.Count - 1
            If GetTabRect(i).Contains(pt) Then Return TabPages(i)
        Next
        Return Nothing
    End Function

    Private Sub SwapPages(ByVal a As TabPage, ByVal b As TabPage)
        If a Is Nothing OrElse b Is Nothing OrElse a.Equals(b) Then Return
        Dim i = TabPages.IndexOf(a), j = TabPages.IndexOf(b)
        TabPages(i) = b : TabPages(j) = a
    End Sub
End Class

Open in new window

0
 
LVL 27

Expert Comment

by:Ark
ID: 40421019
PS. Another approach - using drag'n'drop:
Public Class DraggableTabControl
    Inherits TabControl

    Public Sub New()
        MyBase.New()
        MyBase.AllowDrop = True
    End Sub
    Protected Overrides Sub OnMouseDown(ByVal e As MouseEventArgs)
        If (e.Button = MouseButtons.Left) AndAlso (SelectedTab IsNot Nothing) AndAlso (Not GetTabRect(SelectedIndex).IsEmpty) Then
            DoDragDrop(SelectedTab, DragDropEffects.All)
        End If
        MyBase.OnMouseDown(e)
    End Sub

    Private Sub DraggableTabControl_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragDrop
        If e.Data.GetDataPresent(GetType(TabPage)) Then
            Dim target = TabPageFromPoint(Me.PointToClient(New Point(e.X, e.Y)))
            Dim srcPage = e.Data.GetData(GetType(TabPage))
            SwapPages(srcPage, target)
            Me.SelectedTab = srcPage
        End If
    End Sub

    Private Sub DraggableTabControl_DragOver(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles Me.DragOver
        If e.Data.GetDataPresent(GetType(TabPage)) Then
            Dim target = TabPageFromPoint(Me.PointToClient(New Point(e.X, e.Y)))
            Dim srcPage = e.Data.GetData(GetType(TabPage))
            If target Is Nothing OrElse target.Equals(srcPage) Then
                e.Effect = DragDropEffects.None
            Else
                e.Effect = DragDropEffects.Move
            End If
        End If
    End Sub

    Private Function TabPageFromPoint(ByVal pt As Point) As TabPage
        For i As Integer = 0 To MyBase.TabPages.Count - 1
            If GetTabRect(i).Contains(pt) Then Return TabPages(i)
        Next
        Return Nothing
    End Function

    Private Sub SwapPages(ByVal a As TabPage, ByVal b As TabPage)
        If a Is Nothing OrElse b Is Nothing OrElse a.Equals(b) Then Return
        Dim i = TabPages.IndexOf(a), j = TabPages.IndexOf(b)
        TabPages(i) = b : TabPages(j) = a
    End Sub

End Class

Open in new window

0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

This tutorial demonstrates one way to create an application that runs without any Forms but still has a GUI presence via an Icon in the System Tray. The magic lies in Inheriting from the ApplicationContext Class and passing that to Application.Ru…
1.0 - Introduction Converting Visual Basic 6.0 (VB6) to Visual Basic 2008+ (VB.NET). If ever there was a subject full of murkiness and bad decisions, it is this one!   The first problem seems to be that people considering this task of converting…
This video discusses moving either the default database or any database to a new volume.
This video explains how to create simple products associated to Magento configurable product and offers fast way of their generation with Store Manager for Magento tool.

706 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

19 Experts available now in Live!

Get 1:1 Help Now