Click here to Skip to main content
15,881,204 members
Articles / Programming Languages / Visual Basic
Article

Reordering TabPages inside TabControl

Rate me:
Please Sign up or sign in to vote.
4.57/5 (13 votes)
12 Sep 2006CPOL2 min read 84K   1.2K   22   13
Extending Microsoft TabControl to enable reordering of TabPages

Introduction

When using TabControl in my programs, usually there is one thing users always ask for - "let me reorder those tabs". Since reordering tabs is such a logical operation, one would think that the mighty .NET 2.0 Framework has one. But no luck there. Visual Studio 2005 does have that feature, but mortals are not blessed with it.

Extending

Visual Basic programmers waited for inheritance for far too long so they tend to use it for solving every possible problem (when you have a hammer, all problems look like nails). May I say that here, the same approach will be used.

What we want to do here is to extend the standard TabControl. Inside of it, we are interested in MouseDown, MouseMove and MouseUp events. Some people like to use drag and drop here, but that seems to me like using a bomb to kill a fly.

MouseDown

Upon receiving a MouseDown event, we check if the Left button is used and if TabControl has tab selected. If those requirements are fulfilled, we initialize the SourceTabPage variable.

VB.NET
If (e.Button = Windows.Forms.MouseButtons.Left) AndAlso _
      (MyBase.SelectedTab IsNot Nothing) AndAlso (Not MyBase.GetTabRect_
      (MyBase.SelectedIndex).IsEmpty) Then
  Me._SourceTabPage = MyBase.SelectedTab
End If
MyBase.OnMouseDown(e)

With that, we are ready for further events.

MouseMove

When the mouse is moved, one must check if reordering is in progress. If that is true, we look at what TabPage is under it. If it is not starting one - we have a show.

One of the things we must discover is which TabPage we are hovering over. Since unfortunately, we cannot use some sort of HitText, we must iterate through all TabPages and select one with our coordinates.

VB.NET
Private Function GetTabPageFromXY(ByVal x As Integer, ByVal y As Integer) As TabPage
  For i As Integer = 0 To MyBase.TabPages.Count - 1
    If MyBase.GetTabRect(i).Contains(x, y) Then
      Return MyBase.TabPages(i)
    End If
  Next
  Return Nothing

End Function

After that, we check which side we are hovering. It is only important if you wish to display a different cursor for each side. These two are the ones I use, but you can think of your own schema.

VB.NET
Dim currRect As Drawing.Rectangle = _
      MyBase.GetTabRect(MyBase.TabPages.IndexOf(currTabPage))
If (MyBase.TabPages.IndexOf(currTabPage) < _
      MyBase.TabPages.IndexOf(Me._SourceTabPage)) Then
  MyBase.Cursor = Cursors.PanWest
ElseIf (MyBase.TabPages.IndexOf(currTabPage) > _
      MyBase.TabPages.IndexOf(Me._SourceTabPage)) Then
  MyBase.Cursor = Cursors.PanEast
Else
  MyBase.Cursor = Cursors.Default
End If

MouseUp

Here, we must know on which side we are since the new location (before or after hovering TabPage) depends on this information. This code is basically the same as the one we use for determining the cursor type.

VB.NET
Dim currRect As Drawing.Rectangle = _
      MyBase.GetTabRect(MyBase.TabPages.IndexOf(currTabPage))
If (MyBase.TabPages.IndexOf(currTabPage) < _
      MyBase.TabPages.IndexOf(Me._SourceTabPage)) Then 'bigger then
  MyBase.TabPages.Remove(Me._SourceTabPage)
  MyBase.TabPages.Insert(MyBase.TabPages.IndexOf(currTabPage), Me._SourceTabPage)
  MyBase.SelectedTab = Me._SourceTabPage
ElseIf (MyBase.TabPages.IndexOf(currTabPage) > _
      MyBase.TabPages.IndexOf(Me._SourceTabPage)) Then
  MyBase.TabPages.Remove(Me._SourceTabPage)
  MyBase.TabPages.Insert(MyBase.TabPages.IndexOf(currTabPage) + 1, Me._SourceTabPage)
  MyBase.SelectedTab = Me._SourceTabPage
End If

The only thing after that is clearing things up.

VB.NET
Me._SourceTabPage = Nothing
MyBase.Cursor = Cursors.Default

This is called whether we move anything or not since the user can decide to move our tab to some location where we cannot follow it.

Conclusion

This extended control offers a good solution to reordering TabPages inside a Tab<code>Control. I think that the only thing one may hold against it is updating the order on MouseUp but that decision is made for the sake of speed and code clarity. This way, it is very easy to implement changes through further extending since it uses protected OnMouseX procedures.

Hope you like it.

History

  • 12th September, 2006: Initial post

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Siemens
Croatia Croatia
.NET programmer with MCSD and MCPD status. Loves chevapi...
Medo's Home Page

Comments and Discussions

 
PraiseGreat analysis and coding - I'm impressed! Pin
ChrisRaisin16-Jul-22 18:43
ChrisRaisin16-Jul-22 18:43 
Questiongreat Pin
Southmountain20-Mar-22 12:30
Southmountain20-Mar-22 12:30 
QuestionCSharp version Pin
KendoTM7-Jun-12 21:36
KendoTM7-Jun-12 21:36 
AnswerRe: CSharp version Pin
Josip Medved8-Jun-12 18:46
Josip Medved8-Jun-12 18:46 
QuestionSmall Question Pin
Member 79877066-Jun-12 10:52
Member 79877066-Jun-12 10:52 
AnswerRe: Small Question Pin
Adrao14-Jul-12 4:40
Adrao14-Jul-12 4:40 
GeneralVery helpful article Pin
Anna Novikova1-Jul-10 21:55
professionalAnna Novikova1-Jul-10 21:55 
GeneralMy vote of 5 Pin
Anna Novikova1-Jul-10 21:53
professionalAnna Novikova1-Jul-10 21:53 
GeneralNice Pin
Death8U5-Feb-09 3:07
Death8U5-Feb-09 3:07 
I actually did this in a very similar manner. I agree, I like this method much better than drag n drop.
GeneralDndTabControl functionality. Pin
MijaeDjinn1-Jul-08 10:25
MijaeDjinn1-Jul-08 10:25 
JokeRe: DndTabControl functionality. Pin
Josip Medved21-Jul-08 9:50
Josip Medved21-Jul-08 9:50 
GeneralDndTabControl functionality. Pin
pbnec3-Dec-08 21:35
pbnec3-Dec-08 21:35 
AnswerRe: DndTabControl functionality. Pin
Josip Medved5-Dec-08 4:32
Josip Medved5-Dec-08 4:32 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.