Click here to Skip to main content
15,885,782 members
Articles / Multimedia / GDI+

WinForms Tab Control with properly drawn bottom tabs

Rate me:
Please Sign up or sign in to vote.
4.83/5 (41 votes)
20 Feb 2014CPOL5 min read 188.3K   9.6K   156   39
How to correctly draw WinForms Tab Control with bottom alignment when visual styles are enabled

Image 1

Using UxTabControl

Introduction

Most developers face the same problem when using a tab control with a tab alignment other than Top: when visual styles are enabled, the tabs are drawn incorrectly (to say more precisely - in top orientation only). The same thing happened to me one day. I had a task to convert an old .NET 1.1 application to run under .NET Framework 2.0. I wanted to add visual styles support, and oops - we have a known tab problem. I had been searching the web and had found some solutions, but none of them satisfied me fully. I decided to write my own control UxTabControl by subclassing System.Windows.Forms.TabControl.

You might find my control useful because I think many of you still use Windows Forms and not WPF, and Microsoft hasn't added correct tab drawing for SysTabControl32 even in Windows 8.1. Those guys just require only the top tabs for you to get your application Microsoft certified (by the way, Apple has implemented their tabs correctly in any orientation from stock; you know what I mean if you used Interface Builder deep enough at least once).

Background

I've used the Adi DEDIC article here on CodeProject as a starting point so you can read the Background section from there. Adi explains how to rotate tabs and draw them. My control uses a similar technique. But Adi's control is written in C++ and uses MFC, mine is written mostly in managed code though it uses some platform interops. I have also used some tips about the tab scroller from Mick Doherty's site. You can find the bottom tab control there also in his implementation, but without the source code.

Using the Code

The simplest way of using the control is to add it to your toolbox. To do this, just right-click on the preferred section of the toolbox and then select "Choose items..." in the popped up menu; click "Browse" in the ".NET Framework Components" tab and look for UxTabControl.dll. You're done! Now, you should see UxTabControl in your toolbox, and you can drag it on your form like any other control.

If you don't want to use it in the way described above for some reasons (you aren't using Visual Studio but Notepad and command prompt, for example), you have to add UxTabControl.dll to your project reference libraries. After that, in the code where you are planning to use the control, add the following directive:

C#
using VSControls;

In Visual Basic:

VB.NET
Imports VSControls

In C++/CLI:

C++
using namespace VSControls;

Now, you can create and manipulate UxTabControl the same way as System.Windows.Forms.TabControl

C#
UxTabControl myControl = new UxTabControl();
myControl.Location = new Point(10, 10);
//other code you need

In Visual Basic:

VB.NET
Dim myControl As New UxTabControl
myControl.Location = New Point(10, 10)
'other code you need

In C++/CLI:

C++
UxTabControl^ myControl = gcnew UxTabControl();
myControl->Location = Point(10, 10)
//other code you need

The recommended way to open all the projects and solutions is to use Visual Studio 2013. They all target .NET Framework 4.0 Client Profile (except C++/CLI). If you don't happen to have Professional or more advanced edition of the IDE available, you can download the express edition for Windows desktop from the Microsoft website

Requirements & Limitations

  • .NET Framework 4.0 or newer is required to run the code. Still, after certain modifications, I believe that it's possible to compile the code with older versions of the framework, but not older than 2.0.
  • Custom drawing is not guaranteed to work properly with visual styles other than Microsoft's ones.
  • Supported Windows systems: Vista, 7, 8, 8.1 and their server counterparts. Of course, visual styles must be enabled; otherwise, drawing will be done by the default Windows engine (that's the way I've designed it).
  • Left and right tab alignments aren't supported. I suppose it is not very convenient for a user to lean the head towards the shoulder for a tab's caption to be read, don't you think so? But, if you badly need that feature, you can implement it by yourself.

Points of Interest

  • This article shows how you can subclass some standard .NET controls and override some properties to reach the desired effect.
  • You will learn how to use the System.Windows.Forms.VisualStyles namespace to draw parts of some controls (tab control, in our case).
  • Also, the code shows how to override WndProc to react on some Windows messages.

History

  • 20.03.2009 - Version 1.0
    • Initial version
  • 7.03.2010 - Version 1.0.1
    • Fixed bug with tab text (thanks to SierraMike for reporting). Now text is drawn by GDI instead of GDI+ (I found the solution for "memory bitmap + TextRenderer + ClearType enabled" problem) and so it fits inside tabs
  • 22.02.2013 - Version 1.0.2
    • The control now has a sort of a "transparent" background, i.e., it draws its parent's background on its surface before drawing itself.
    • The RightToLeft and RightToLeftLayout properties are no longer disabled. They were disabled in previous versions due to painting problems.
    • The control has been renamed to UxTabControl (after uxtheme.dll). The previous name was bound to a particular version of Windows and that is not quite accurate.
    • The support for Windows XP and 2003 has been dropped. I consider these operating systems obsolete.
  • 2.02.2014 - Version 1.0.3
    • Some people didn't like unsafe code used in the C# project. Well, that one has been replaced with the help of the magic structure System.Runtime.InteropServices.GCHangle. It's the unified approach in all the projects you can download from this article.
    • A C++/CLI project has been added for the complete set. 

License

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


Written By
Team Leader Scand Ltd.
Belarus Belarus
I've have been programming since 1998. I started from command line applications written in Express Pascal 2.0 under CP-M. In 2002 I learned C++ and was programming using Borland C++ Builder. In 2005 I discovered .NET for myself. I did some occasional Java programming as well. In the end, it's not a language or a technology that matters, it's how you use it. Currently I'm doing Web development.

Comments and Discussions

 
QuestionOld wine new bottels Pin
Michael Pauli4-Sep-14 23:06
Michael Pauli4-Sep-14 23:06 
AnswerRe: Old wine new bottels Pin
Vladimir Svyatski8-Sep-14 1:37
professionalVladimir Svyatski8-Sep-14 1:37 
QuestionNice VUreal! Pin
Volynsky Alex20-Feb-14 23:52
professionalVolynsky Alex20-Feb-14 23:52 
GeneralMy vote of 5 Pin
JayantaChatterjee4-Feb-14 1:11
professionalJayantaChatterjee4-Feb-14 1:11 
AnswerRe: My vote of 5 Pin
Vladimir Svyatski4-Feb-14 4:47
professionalVladimir Svyatski4-Feb-14 4:47 
QuestionNice VUnreal! Pin
Volynsky Alex3-Feb-14 11:08
professionalVolynsky Alex3-Feb-14 11:08 
GeneralMy vote of 5 Pin
Casey Sheridan29-Aug-13 13:02
professionalCasey Sheridan29-Aug-13 13:02 
GeneralMy vote of 5 Pin
Southmountain24-Jul-13 13:10
Southmountain24-Jul-13 13:10 
SuggestionSide Tabs Pin
Jalapeno Bob5-Mar-13 6:54
professionalJalapeno Bob5-Mar-13 6:54 
GeneralMy vote of 5 Pin
rspercy6523-Feb-13 14:03
rspercy6523-Feb-13 14:03 
QuestionNice one Pin
wmjordan22-Feb-13 22:41
professionalwmjordan22-Feb-13 22:41 
AnswerRe: Nice one Pin
Vladimir Svyatski24-Feb-13 9:14
professionalVladimir Svyatski24-Feb-13 9:14 
GeneralRe: Nice one Pin
wmjordan26-Feb-13 21:34
professionalwmjordan26-Feb-13 21:34 
GeneralThats great! Pin
vlad7817-Jun-11 9:22
vlad7817-Jun-11 9:22 
AnswerRe: Thats great! Pin
Vladimir Svyatski8-Jun-11 10:09
professionalVladimir Svyatski8-Jun-11 10:09 
GeneralRe: Thats great! Pin
vlad7818-Jun-11 18:14
vlad7818-Jun-11 18:14 
GeneralRe: Thats great! Pin
Vladimir Svyatski12-Jun-11 11:14
professionalVladimir Svyatski12-Jun-11 11:14 
GeneralRe: Thats great! Pin
vlad78113-Jun-11 15:51
vlad78113-Jun-11 15:51 
GeneralMy vote of 5 Pin
Global Analyser5-Nov-10 8:49
Global Analyser5-Nov-10 8:49 
QuestionChange background color? Pin
bobmck16-Oct-10 2:34
bobmck16-Oct-10 2:34 
AnswerRe: Change background color? Pin
Vladimir Svyatski18-Oct-10 10:34
professionalVladimir Svyatski18-Oct-10 10:34 
QuestionWhat about a Close-Button (X) Pin
T_uRRiCA_N20-Jun-10 22:43
professionalT_uRRiCA_N20-Jun-10 22:43 
AnswerRe: What about a Close-Button (X) Pin
Vladimir Svyatski21-Jun-10 9:13
professionalVladimir Svyatski21-Jun-10 9:13 
GeneralRe: What about a Close-Button (X) Pin
wmjordan26-Feb-13 21:39
professionalwmjordan26-Feb-13 21:39 
GeneralMissing Left & Right Pin
Mc Gwyn18-Nov-09 2:19
Mc Gwyn18-Nov-09 2:19 

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.