Click here to Skip to main content
Licence 
First Posted 8 Dec 2006
Views 81,358
Downloads 2,254
Bookmarked 86 times

A Tab Control Similar to that of Internet Explorer 7

By | 8 Dec 2006 | Article
A (fairly) simple tab control with closeable tabs
Sample Image - TabPages.jpg

Introduction

Recently, several of my projects have required the ability to handle multiple documents. I figured IE7's tabs were a pretty good way of handling this, and here is the control that resulted.

Overview

This control is basically a managed collection of pages (or controls). It is event driven, indicating when a page has been added, removed, selected, or closed. The close event is cancellable, allowing you to prevent pages from being closed unless certain criteria are met.

I should probably add that there is no support for adding tabs via the IDE. I'd considered doing this, but it didn't really make sense. All of my projects are dealing with documents which will be opened and closed at runtime, and so I designed this control with that in mind.

Using the Control

Creating the Control

To create the control, add a reference to TabPages.dll, then create the TabPages.PageCollection control either programmatically or through the IDE.

Adding Pages

To add a page, call the Add method. This method takes a TabPage object as a parameter.  The TabPage object has text, a control (the control you wish to display when the tab is selected), and an optional toolTip string which will be displayed when the mouse hovers over the tab.

Removing Pages

To remove a page, call the Remove, RemoveAt, or Clear methods. These methods correspond to IList(Of TabPage) methods.

You can also call the Close method of the TabPage you wish to close (this will raise the PageClosing event, whereas the Remove methods will not).

Events

There are several events which will be of interest to users of the PageCollection control, and they are defined as follows:

Public Event PageAdded(ByVal page As TabPage)

Public Event PageRemoved(ByVal page As TabPage)

Public Event CurrentPageChanged_
	(ByVal currentPage As TabPage, ByVal previousPage As TabPage)

Public Event PageClosing(ByVal page As TabPage, ByRef cancel As Boolean)

The PageAdded event fires when a page is added to the collection.

The PageRemoved event fires when a page is removed from the collection.

The CurrentPageChanged event fires when the currently selected page changes (when a different tab becomes the active tab). This event gets passed the currently selected tab as well as the previously selected tab.

The PageClosing event fires when a page is attempting to close. This gets fired when the user clicks close, or when the TabPage's Close method is called. This does not fire when Remove, RemoveAt, or Clear are called. The page parameter indicates which page is attempting to close, and the cancel parameter allows cancellation of the close. If the close is not cancelled, the page will be removed from the collection and the PageRemoved event will fire.

Appearance

The appearance of this control could be more flexible, but for now, it is adequate. There are two properties of interest when customizing the PageCollection control's appearance.

The TabColor property specifies the color which will be used to generate the control's theme. All gradients, borders, and menu colors are generated from this color. Play around with it and see what you like. My favorite TabColors are LightGray and LightSteelBlue.

The TopMargin property specifies the difference between the height of the selected tab and the non selected-tabs.

Points Of Interest

As I said earlier, this control is pretty simple.  But there were two semi-challenges while developing it.

Flickering

The initial version flickered something awful, even though I was double buffering. I was able to get around this by passing the WM_SETREDRAW message to the SendMessage API method.  It's now smooth as... er... Bono or some similarly smooth person.

Private Const WM_SETREDRAW As Integer = &HB

Private Declare Auto Function SendMessage Lib "User32" Alias "SendMessage" _
	(ByVal hWnd As IntPtr, ByVal msg As Integer, _
	ByVal wParam As Integer, ByVal lParam As Integer) As Boolean

What was happening is each time I resized (or added/removed controls), I would regenerate the list of displayed tab controls. Each time the list was regenerated, each tab would invalidate. It was ugly. WM_SETREDRAW basically tells a handle (control) that you don't want it to paint any more until you say so. For more information on this, see the FlickerFreeControl in the project.

Menu Theme

The other thing I wanted was menus which matched the color scheme of the tabs. To accomplish this, I inherited from the ToolStripRenderer.  I'd never used this before, but what it allows you to do is customize the painting of a toolstrip object (in this case, my context menu). See the DropDownRenderer class in the source for the implementation.

Conclusion

I'm not going to repeat myself.  I hope you like this control. If you make significant improvements to it, please send them my way so I can capitalize on them. Peace.

History

  • 8th December, 2006: Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

christophilus

Software Developer

United States United States

Member

I'm a professional geek.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
Generaltab pages PinmemberTsoperas2:27 18 Feb '11  
QuestionHow can i use this "dll" in C# Project ? Pinmemberhiman13654:24 15 Sep '10  
GeneralNew C# version Pinmemberprozomg4:54 2 Jan '10  
GeneralRe: New C# version PinmemberLloyd Atkinson6:43 15 Sep '10  
Generalblank page after minimize application PinmemberDonSalieri865:57 17 Sep '09  
QuestionChange background color PinmemberRadu_205:30 20 Jan '09  
GeneralAny suggestions Pinmembereyanson8:24 14 Jan '09  
QuestionHi PinmemberRadu_202:18 13 Jan '09  
GeneralVS 2008 C# version Pinmemberwejaya8:20 2 Dec '08  
GeneralVS 2008 c# version Pinmembersodevrom11:03 17 Nov '08  
GeneralRe: VS 2008 c# version PinmemberCaglow9:15 22 Nov '08  
GeneralRe: VS 2008 c# version PinmemberMicheleLaPietra1:08 17 Sep '09  
QuestionC# implementation Pinmemberleyroyjenkins14:51 2 Oct '08  
AnswerRe: C# implementation PinmemberCaglow11:15 19 Oct '08  
GeneralRe: C# implementation Pinmembersodevrom3:55 10 Nov '08  
AnswerRe: C# implementation PinmemberOsama Ibrahim1:07 15 Nov '08  
GeneralRe: C# implementation Pinmembersodevrom8:29 16 Nov '08  
GeneralWhy didn't you implement it as a subclassed control? [modified] PinmemberPaul Owen0:56 2 Apr '08  
GeneralLicensing PinmemberSam N4:50 8 Feb '08  
GeneralA very nice control - a couple of suggestions. Pinmembergabriel6623:44 22 Oct '07  
GeneralRe: A very nice control - a couple of suggestions. PinmemberThord Johansson11:23 7 Mar '09  
As for 1. TabCollection.Item Wink | ;)
GeneralUsage terms and conditions Pinmemberkumar4314:38 1 Sep '07  
GeneralNice Tab Control - One Suggestion Pinmemberviettho12:29 4 Jun '07  
GeneralVisual Studio 2003 keeps throwing error... Pinmembercdawg12:17 20 Apr '07  
GeneralVery nice work PinmemberMarek Bohac22:57 16 Mar '07  

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.

Permalink | Advertise | Privacy | Mobile
Web01 | 2.5.120604.1 | Last Updated 8 Dec 2006
Article Copyright 2006 by christophilus
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid