Solved

Movable Tabs on Tabcontrol

Posted on 2014-11-03
4
131 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

ScreenConnect 6.0 Free Trial

Explore all the enhancements in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
Introduction When many people think of the WebBrowser (http://msdn.microsoft.com/en-us/library/2te2y1x6%28v=VS.85%29.aspx) control, they immediately think of a control which allows the viewing and navigation of web pages. While this is true, it's a…
This video shows how to use Hyena, from SystemTools Software, to bulk import 100 user accounts from an external text file. View in 1080p for best video quality.
Established in 1997, Technology Architects has become one of the most reputable technology solutions companies in the country. TA have been providing businesses with cost effective state-of-the-art solutions and unparalleled service that is designed…

810 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