Solved

Movable Tabs on Tabcontrol

Posted on 2014-11-03
4
136 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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 34

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 28

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 28

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

Creating Instructional Tutorials  

For Any Use & On Any Platform

Contextual Guidance at the moment of need helps your employees/users adopt software o& achieve even the most complex tasks instantly. Boost knowledge retention, software adoption & employee engagement with easy solution.

Question has a verified solution.

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

It’s quite interesting for me as I worked with Excel using vb.net for some time. Here are some topics which I know want to share with others whom this might help. First of all if you are working with Excel then you need to Download the Following …
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…
There's a multitude of different network monitoring solutions out there, and you're probably wondering what makes NetCrunch so special. It's completely agentless, but does let you create an agent, if you desire. It offers powerful scalability …

690 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