Click here to Skip to main content
11,491,742 members (69,038 online)
Click here to Skip to main content

MdiTabStrip

, 6 Jul 2007 CPOL 220.7K 9.5K 203
Rate this:
Please Sign up or sign in to vote.
Tabbed control for MDI applications

Sample Image

Introduction

I have read a lot of articles here on the CodeProject site and have greatly appreciated the work and ideas that everyone here has shared, so I decided to share this control as payback. The MdiTabStrip was developed out of the need to have a tabbed interface for an MDI application I am working on. I really liked the look and functionality of the Internet Explorer 7 tab control, so this became the basis for my control. It is not an exact replica, but it has a lot of similar features, as you will see in the demo. The only things missing that I wish could be included are the buttons and drop-down buttons of the IE7 control. I have a working version of a control that inherits from the ToolStrip component, but because the ToolStripDesigner class is not public and thus cannot be inherited, I can't add the designer experience I want for the tabs. I may post it one day if someone requests it, but for now it is still a work in progress.

My testing environment is very narrow, so I will appreciate any feedback as to how the control performs. Also, if there are any comments, suggestions and even complaints that you want to share, by all means do so. If there is a better way of doing something, I am always interested in learning. I hope someone finds this control useful. If not in whole, then maybe some part of it.

Background

This control is based on a windowless concept in which the control and its constituent parts only use one window handle. The tabs for each MDI child window and the tabs for scrolling appear to be separate controls that act independently of each other. However, the painting, layout, mouse events and drag-drop events are all handled by the container control. It was after reading an article here on CodeProject by Alexey A. Popov: "Extending Windows Forms - lightweight views" and studying the ToolStrip control using Lutz Roeder's .NET Reflector that I began to understand the power and flexibility of a windowless control. When looking at the IE7 tab control, I realized that the best way to reproduce it would be to use this method.

Using the code

There are really only two things you need to do to be up and running with this control. Add it to your form and set the form's IsMdiContainer property to True. Since the MdiTabStrip hooks into the parent form's MdiChildActivated event, it will automatically add a tab to its collection when a new form is opened as an MDI child. If this event is raised and a tab already exists for the child form, then this tab is made active. Each tab ties itself to its related form and hooks to this form's FormClosed event. It is through this event that the tab is removed from the collection.

Points of interest

Besides duplicating -- although not exactly -- the visual look of the IE7 tab control, it also duplicates most of its functionality. You can set a maximum and minimum width for the tabs. These settings come into play when you resize the form. The tabs will scale their size according to the amount of space available. When their size is below the set minimum, they start to disappear. This is when the scroll tabs become visible.

You can rearrange the order of each tab by dragging and dropping them to a new location. The control draws indicators as to where the tab will be positioned if dropped at the current location of the mouse pointer. I also included a custom cursor for the drag operation.

With the drop-down menu tab, you can select which form to activate via a menu. The currently active form's menu item is checked and when the tab for the form is currently hidden -- because there is not enough room to display it -- the background of the menu item is a light gray.

I have added a lot of customizability to this control, although I am sure I left something out that someone will ask for. There are basically three "types" of tabs: Active, InActive, and MousedOver. For these tab types, you can set the tab background color, foreground color, border color and font. I had hoped to create a designer that was similar to the ToolStrip's designer where, as you clicked on each item of the ToolStrip, the Property Browser window would show that item's properties. After studying the designer with .NET Reflector, I found that the switching between components was done via a method that was not public. So, giving up on this, I created a designer that used a form with a PropertyGrid control and used my own logic to set the grid's SelectedObject property.

I commented the code as much as I could to try and explain what was being done and why. I recommend opening the included demo and trying out the control. Some things are better understood seeing them in action than reading about them.

History

  • 5 Jan 2007 - Original version posted.
  • 8 Jan 2007 - Updated demo download.
  • 16 Apr 2007 - Version 1.5 - Fixes and enhancements.
    1. Enhancement - Added a drop shadow behind the close button glyph. This gives the glyph a little more dimension.
    2. Fix – Although not truly a bug, the resizing of the control did not behave correctly. The proposed width for the tabs was based on whole numbers. Let's say you had four tabs open and you were resizing the parent form smaller and smaller and you got to the point where the proposed width for each tab was smaller than the minimum width allowed. You would have to resize the window 4 pixels before the tab width would scale again. If you had ten tabs open, it would take 10 pixels before the tabs would resize. This update calculates a proposed width the same way as before but also takes into account any remainder left over from this calculation and evenly distributes it between the tabs.
    3. Changed the Text property for the MdiTab class. It now shadows the Control.Text property and returns the text of the Form it is tied to. Setting the Text property does nothing.
    4. Added the following events:
      • CurrentMdiTabChanged
      • MdiTabAdded
      • MdiTabClicked
      • MdiTabIndexChanged
      • MdiTabRemoved
    1. Added two new classes to handle the event arguments for the above events: MdiTabStripTabClickedEventArgs and MdiTabStripTabEventArgs.
    2. The MdiTabStrip will now correctly draw the image set as the BackgroundImage.
    3. Due to so many requests, I decided to add in a fix for the display issues noted when opening the first form, when switching between tabs and the control box displaying when no MenuStrip is on the parent form. Although this is not a problem with the MdiTabStrip control and these problems still occur even if this control is not on the form, I decided to incorporate the fix that was suggested by Patrick Sears. Thank you, Patrick. I added a new property called MdiWindowState that has two possible values: Normal and Maximized. When set to Normal, you control each form's appearance through its properties. When set to Maximized, the MdiTabStrip will change each form's properties concerning the form's border, control box and docking.
  • 22 Apr 2007 - Fixes and Enhancements.
    1. Added support for RightToLeft.
    2. Fixed bug where if the Form's Text property was changed, the tab's text did not update correctly and the drop-down item's text did not update at all.
  • 6 Jul 2007 - Version 1.5.5 Fixes and Enhancements.
    1. Added NewMdiTab class
      • Class exposes event named OnMdiNewTabClicked. A developer can handle this event to open a new form of choice.
      • Three new properties that are used for this class: MdiNewTabImage, MdiNewTabVisible and MdiNewTabWidth. If no image is specified then a default one is used.
    2. Added tooltips for tabs.
      • Two new properties for this feature: ShowTabToolTip and NewTabToolTipText.

License

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

Share

About the Author

crcrites

United States United States
No Biography provided

Comments and Discussions

 
QuestionPlease Update it for Framework 4.0 Pin
controlsky18-Oct-14 8:48
membercontrolsky18-Oct-14 8:48 
QuestionCompatibility problem with Framework 4 Pin
Member 476126216-Jan-14 1:51
memberMember 476126216-Jan-14 1:51 
QuestionMdiTabStrip in visual studio express 2010/12? Pin
Luciano AP5-Nov-13 11:39
memberLuciano AP5-Nov-13 11:39 
QuestionDoes not work on framework 4 Pin
Member 202943415-May-12 13:56
memberMember 202943415-May-12 13:56 
QuestionDrag drop - autofocus tab Pin
Homebunny20-Jan-12 5:03
memberHomebunny20-Jan-12 5:03 
QuestionConvert Text to Bitmap/Drawing instead Pin
AETCoder25-Oct-11 6:39
memberAETCoder25-Oct-11 6:39 
QuestionSelecting Tab Pin
Member 202943416-Aug-11 2:59
memberMember 202943416-Aug-11 2:59 
GeneralNet Framework 4 Pin
AETCoder31-May-11 10:09
memberAETCoder31-May-11 10:09 
GeneralThe error Pin
AETCoder30-May-11 12:12
memberAETCoder30-May-11 12:12 
GeneralRe: The error Pin
MozgC29-Oct-11 14:37
memberMozgC29-Oct-11 14:37 
Generalhow to use in vb 2010 Pin
harrymaulana19-Apr-11 7:04
memberharrymaulana19-Apr-11 7:04 
QuestionI came across a problem Pin
AETCoder10-Apr-11 11:30
memberAETCoder10-Apr-11 11:30 
GeneralRe: I came across a problem [modified] Pin
AETCoder19-May-11 7:21
memberAETCoder19-May-11 7:21 
GeneralRe: I came across a problem [modified] Pin
MozgC29-Oct-11 14:38
memberMozgC29-Oct-11 14:38 
QuestionTabbed Windows Pin
emadaljundi14-Apr-10 4:38
memberemadaljundi14-Apr-10 4:38 
GeneralI've added some enhancements to tooltips... Pin
claudio785-Feb-10 13:30
memberclaudio785-Feb-10 13:30 
GeneralRe: I've added some enhancements to tooltips... Pin
rojaldearintok29-Aug-13 8:01
memberrojaldearintok29-Aug-13 8:01 
QuestionMain Functions Pin
cerembeyazit28-Nov-09 10:07
membercerembeyazit28-Nov-09 10:07 
GeneralGet a warning about needing "flash.ocx" on exiting app using MdiTabStrip Pin
nzmike10-Apr-09 14:11
membernzmike10-Apr-09 14:11 
GeneralFixing the "Tooltips show even if you set ShowTabToolTip to false" issue Pin
MozgC28-Mar-09 6:21
memberMozgC28-Mar-09 6:21 
GeneralRe: Fixing the "Tooltips show even if you set ShowTabToolTip to false" issue Pin
jtxd16-Feb-12 15:30
memberjtxd16-Feb-12 15:30 
GeneralFixing the flicker (blinking when switching tabs) issue. Pin
MozgC28-Mar-09 6:13
memberMozgC28-Mar-09 6:13 
GeneralRe: Fixing the flicker (blinking when switching tabs) issue. Pin
MozgC10-Apr-09 15:35
memberMozgC10-Apr-09 15:35 
GeneralPosition nuance... Pin
igpf23-Jan-09 6:30
memberigpf23-Jan-09 6:30 
QuestionAny way to prevent new tabs from stealing focus? Pin
JiveMasterT1-Jul-08 12:29
memberJiveMasterT1-Jul-08 12:29 
GeneralDisable a particular Tab Pin
andrew_16626-May-08 8:20
memberandrew_16626-May-08 8:20 
GeneralPlease Help!! Pin
chirantan.sriram2-Apr-08 5:40
memberchirantan.sriram2-Apr-08 5:40 
GeneralRe: Please Help!! Pin
AdamGlowka13-Nov-08 16:25
memberAdamGlowka13-Nov-08 16:25 
GeneralRe: Please Help!! Pin
MozgC30-Oct-11 15:49
memberMozgC30-Oct-11 15:49 
Questioneach Tab with another color Pin
MetalPower26-Mar-08 11:54
memberMetalPower26-Mar-08 11:54 
Generallicense Pin
adamthomassnider7-Feb-08 16:49
memberadamthomassnider7-Feb-08 16:49 
Questionclose a form using CTRL+F4 Pin
tmehta23-Jan-08 1:08
membertmehta23-Jan-08 1:08 
AnswerRe: close a form using CTRL+F4 Pin
alp can5-Aug-08 6:15
memberalp can5-Aug-08 6:15 
QuestionMdiTabStrip problem Pin
necroline17-Sep-07 6:28
membernecroline17-Sep-07 6:28 
GeneralClose button on right upper corner Pin
Jason Law13-Sep-07 20:48
memberJason Law13-Sep-07 20:48 
QuestionMDITabStrip - license Pin
Freebreaker10-Sep-07 22:55
memberFreebreaker10-Sep-07 22:55 
GeneralReordering Tabs Pin
cdm200710-Sep-07 18:11
membercdm200710-Sep-07 18:11 
GeneralToolstripContainer Pin
morphias0@yahoo.com31-Aug-07 8:16
membermorphias0@yahoo.com31-Aug-07 8:16 
GeneralRe: ToolstripContainer Pin
morphias0@yahoo.com31-Aug-07 8:54
membermorphias0@yahoo.com31-Aug-07 8:54 
QuestionKeep mdi child Maximised? Pin
Kestrel_rob30-Aug-07 5:06
memberKestrel_rob30-Aug-07 5:06 
AnswerRe: Keep mdi child Maximised? Pin
Kestrel_rob30-Aug-07 5:16
memberKestrel_rob30-Aug-07 5:16 
AnswerRe: Keep mdi child Maximised? [modified] Pin
morphias0@yahoo.com31-Aug-07 9:19
membermorphias0@yahoo.com31-Aug-07 9:19 
GeneralAccessing properties of controls on tabs Pin
seanwright29-Aug-07 18:44
memberseanwright29-Aug-07 18:44 
AnswerRe: Accessing properties of controls on tabs Pin
morphias0@yahoo.com31-Aug-07 8:21
membermorphias0@yahoo.com31-Aug-07 8:21 
GeneralTab close. part deux Pin
seanwright29-Aug-07 18:32
memberseanwright29-Aug-07 18:32 
GeneralRe: Tab close. part deux Pin
morphias0@yahoo.com31-Aug-07 8:22
membermorphias0@yahoo.com31-Aug-07 8:22 
QuestionDisable a particular close button? Pin
seanwright29-Aug-07 18:03
memberseanwright29-Aug-07 18:03 
AnswerRe: Disable a particular close button? Pin
radioman.lt@gmail.com29-Apr-08 5:25
memberradioman.lt@gmail.com29-Apr-08 5:25 
QuestionUpsideDown ? Pin
PL0122-Aug-07 12:52
memberPL0122-Aug-07 12:52 
GeneralPersisting Tabs after close Pin
VisuallyBasicNet26-Jul-07 21:30
memberVisuallyBasicNet26-Jul-07 21:30 

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

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

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.150520.1 | Last Updated 6 Jul 2007
Article Copyright 2007 by crcrites
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid