I am developing a Windows Form Application with several pages. I am using a TabControl to implement this. Instead of using the header to switch between tabs, I want my application to control this e.g. the next tab should open after the user has filled in a text box and clicked the next button.
-
@Dan W How is a `TabPage` without the top thumb/selector significantly different than a `Panel`? – Ňɏssa Pøngjǣrdenlarp Apr 19 '15 at 23:11
-
1@Plutonix: Because in the designer, it would be a lot easier to switch between different groups of widgets by switching tabs. – Dan W Apr 20 '15 at 16:52
-
`myPanelTabs(n).BringToFront` Done. or mess with visible. – Ňɏssa Pøngjǣrdenlarp Apr 20 '15 at 17:00
-
2@Plutonix: That's code though, I want to be able to switch what's in a given area from the Forms designer with a single click actually while I'm in the Forms designer. – Dan W Apr 21 '15 at 21:25
-
@MickyDuncan: The program as it appears to the user would be anything but a wizard. They only see one of the tabs according to the software version they choose, and the other tabs/pages are permanently inaccessible as they would be irrelevant. But yes, a developer could use the idea to implement a wizard type system. – Dan W Apr 23 '15 at 20:55
-
@MickyDuncan: Er, yes it can be used for that too. I'm sure there are lots of uses for hiding the tab switcher/header to the user, but showing it to the developer. Sorry, not quite sure what your point is. – Dan W Apr 24 '15 at 00:46
-
@MickyDuncan: You mean `DesignMode` presumably? A UserControl may be possible to create, but that would negate the functionality that a standard TabControl offers, so I guess such an answer would be presumably pretty involved. By all means, add an answer if you think it'd be simple to code (however, such an answer would be unrelated to the bounty I've offered, unless it solved that by chance too). – Dan W Apr 24 '15 at 01:03
10 Answers
Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form. It shows the tabs at design time so you can easily switch between them while designing. They are hidden at runtime, use the SelectedTab or SelectedIndex property in your code to switch the page.
using System;
using System.Windows.Forms;
public class TablessControl : TabControl {
protected override void WndProc(ref Message m) {
// Hide tabs by trapping the TCM_ADJUSTRECT message
if (m.Msg == 0x1328 && !DesignMode) m.Result = (IntPtr)1;
else base.WndProc(ref m);
}
}

- 922,412
- 146
- 1,693
- 2,536
-
22Erm, it's not an opinion. This works well on all Windows versions. – Hans Passant Aug 05 '11 at 10:57
-
-
4Hi, could you update your code in the case where the left/right arrows disappear too? (They otherwise show when there are more tabs than can be contained by the StackPanel box). Thanks so much; being able to switch views like this on the fly is incredibly handy. – Dan W Jul 29 '12 at 22:11
-
1Please edit your example from `class TablessControl` to `public class TablessControl` to make it show up in the Toolbox when using it from a different assembly. – Nebula Nov 29 '12 at 09:11
-
-
I tried one of the other work-arouns, I suspect this idea may have the same issue where pressing Ctrl-Tab will switch between the tabs, possibly an issue.. – Mark Redman Aug 10 '13 at 08:06
-
1
-
Works like a charm - unless you have the TabControl set to disallow multiple rows of tabs (MultiLine property set to False). You may want to add a line to the code to force that property to True, or you end up with hidden tabs, but tab navigation buttons still showing... – Nick Shaw Feb 23 '15 at 10:31
-
@HansPassant: In my newly created answer, is Solution 3 safe in terms of DPI and resolution for the user? – Dan W Apr 17 '15 at 19:43
-
1Probably. You could just set the SizeMode to Fixed and ItemSize.Width to 0 in OnHandleCreated if DesignMode is false. Never a problem that way. – Hans Passant Apr 17 '15 at 20:23
-
2I think you also want to override the OnKeyDown method in this class to filter out Ctrl+Tab events. if (ke.KeyCode == Keys.Tab && ke.Control)... – Eric Hirst Mar 30 '16 at 18:22
-
This solution has some side effects as it shifting controls location in Visual Studio designer after editing UI – volody May 24 '18 at 20:11
-
When I drag it from the ToolBox, I get an error `Failed to load ToolBox item 'Tabless control'. It will be removed from the ToolBox` and it dissapears. I need to build the program again for it to appear. What might be the cause ? – mrid May 08 '20 at 10:14
-
tabControl1.Appearance = TabAppearance.FlatButtons;
tabControl1.ItemSize = new Size(0, 1);
tabControl1.SizeMode = TabSizeMode.Fixed;

- 2,274
- 23
- 23
-
-
1That is by far the easiest way, that worked well for me.You could do it in the designer's properties if you wish. – dmihailescu Jul 31 '15 at 19:40
-
-
It's a shame that the very best answer to this has *zero* explanation behind it. You can set everything but `ItemSize` in the designer props and simply set the `ItemSize` on `PageLoad`. This should be the top answer IMHO. MS should just have this feature as an option though. – krowe2 Jan 05 '16 at 16:41
-
2
Create new UserControl, name it for example TabControlWithoutHeader and change inherited UserControl to TabControl and add some code. Result code should look like:
public partial class TabControlWithoutHeader: TabControl
{
public TabControlWithoutHeader()
{
InitializeComponent();
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x1328 && !DesignMode)
m.Result = (IntPtr)1;
else
base.WndProc(ref m);
}
}
After compile you will have TabControlWithoutHeader control in ToolBox. Drop it on form, in designer you will see headers, but at runtime they'll be hidden. If you want to hide them in designer too, then remove && !DesignMode
.
Hope that helps.

- 169
- 3
- 11

- 11,694
- 1
- 43
- 62
-
1
-
2
-
Hans is saying he already posted this answer. You just copied it and posted it again. – Cody Gray - on strike Apr 24 '13 at 06:29
-
@volody Hans posted it on MSDN (under his MSDN name Nobugz) [back in 2007](http://social.msdn.microsoft.com/Forums/windows/en-US/c290832f-3b84-4200-aa4a-7a5dc4b8b5bb/tabs-in-winform?forum=winforms)... – Matthew Watson Mar 07 '14 at 09:41
-
1Ok I'am not a wizard to know who is creator of original code and especially who hides under different nickname in different site. So thank you @MatthewWatson for explanation what other where talking about. :) – Renatas M. Mar 14 '14 at 11:40
You can replace tabcontrol with a hand made panel that mimic like you want:
class MultiPagePanel : Panel
{
private int _currentPageIndex;
public int CurrentPageIndex
{
get { return _currentPageIndex; }
set
{
if (value >= 0 && value < Controls.Count)
{
Controls[value].BringToFront();
_currentPageIndex = value;
}
}
}
public void AddPage(Control page)
{
Controls.Add(page);
page.Dock = DockStyle.Fill;
}
}
And then add pages and set current visible page:
MultiPagePanel p;
// MyTabPage is a Control derived class that represents one page on your form.
MyTabPage page = new MyTabPage();
p.AddPage(page);
p.CurrentPageIndex = 0;

- 6,358
- 2
- 34
- 70

- 201
- 1
- 4
-
2just stumbled on this thread and found an error: if (value >= 0 && value < (Controls.Count - 1)) should be if (value >= 0 && value < Controls.Count). otherwise you will miss some panels. – benst Jul 02 '13 at 14:11
I was needing this code but in VB.net so I converted it. If someone needs this code in VB.Net there it is
Imports System
Imports System.Windows.Forms
Public Class TablessControl
Inherits System.Windows.Forms.TabControl
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
' Hide tabs by trapping the TCM_ADJUSTRECT message
If (m.Msg = Convert.ToInt32("0x1328", 16) And Not DesignMode) Then
m.Result = CType(1, IntPtr)
Else
MyBase.WndProc(m)
End If
End Sub
End Class
and thanks to @Hans Passant for the answer in C#

- 525
- 1
- 10
- 19
-
Interesting idea. Here's a C# version of the solution you described in VB.NET: https://blog.laplante.io/2011/01/hiding-tab-headers-on-a-tabcontrol-in-c/ – Matt Aug 22 '19 at 07:51
To complement Hans Passant's existing answer, I've found four ways to hide the arrows from the user when the numbers of tabs exceeds the width of the TablessControl. No single solution is necessarily perfect for everyone, but may be for you (or at least a combination of them).
Solution 1:
Simply enable Multiline
. This will prevent the arrows from appearing in the first place. However, bear in mind, you may lose WYSIWYG in the designer because the vertical space will be adjusted downwards vertically, and controls within the TablessControl may even be 'chopped off' at the bottom (again, only in developer mode though).
Solution 2:
A more advanced solution which solves the WYSIWYG problem above is to only enable Multiline
once the program gets running. Simply add this constructor to the TablessControl class:
public TablessControl()
{
bool designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
if (!designMode) Multiline = true;
}
To the developer, they will still appear as a single line of tabs.
Solution 3:
Decrease the font size of the TablessControl. Each tab should shrink accordingly. Since the user never gets to see the tabs, it shouldn't matter much if you set the font sizes to even 4pt.
However be careful, because the TablessControl's contents may also be resized. If this happens, re-edit the font size for each widget inside, and at that point, they'll thankfully stay at that size even if you then decide to re-change the main TablessControl's font size again.
This approach also has the advantage of more closely showing the true WYSIWYG vertical real-estate to the developer (which can look fine for the user, but may be cut off slightly at the bottom in the designer due to the height of the tabs).
This solution can be combined with Solution 1 and 2 for accumulated advantages.
Solution 4:
This solution isn't necessarily so great if any of the tabs have text which are long. Thanks to Hans for suggesting it.
First set the TablessControl's SizeMode
to 'Fixed', and then reduce the TablessControl's ItemSize
Width
property to a smaller number to reduce each tab's width. Feel free also to adjust the ItemSize
Height
property to help address the aforementioned WYSIWYG issue, though Solution 3 may be more helpful for that problem.
This solution can be combined with the above solutions to further accumulate advantages.

- 3,520
- 7
- 42
- 69
If you really want to do this, yo can do something like this
tcActionControls.Region = new Region(new RectangleF(
tbPageToShow.Left,
tbPageToShow.Top,
tbPageToShow.Width,
tbPageToShow.Height)
);
Where tcActionControls
is your TabControl
and tbPageToShow
is a TabPage
to show in this precise moment.
Should work for you.
Regards.

- 61,654
- 8
- 86
- 123
This solution appears to work well - How to hide tabs in the tab control?
Insert Tabcontrol into a form, the default name being tabcontrol1.
Ensure that tabcontrol1 is selected in the Properties pane in visual studio and change the following properties:
a. Set Appearance to Buttons
b. Set ItemSize 0 for Width and 1 for Height
c. Set Multiline to True
d. Set SizeMode to Fixed
This is best done after your have finished your design time tasks as it hides them in the designer as well - making it difficult to navigate!

- 47,830
- 31
- 106
- 135

- 103
- 1
- 3
- 15
You can try removing the TabPage from the TabPageCollection :
TabControl.TabPageCollection tabCol = tabControl1.TabPages;
foreach (TabPage tp in tabCol)
{
if(condition)
{
tabCol.Remove(tp);
}
}

- 9
- 2
-
The question is about removing the HEADER ROW (containing the names of the tabs) at the top of the visible tab contents. This is not an answer to that question. – ToolmakerSteve May 20 '17 at 09:28
-
tabControl.Appearance = TabAppearance.FlatButtons; tabControl.ItemSize = new Size(0, 1); tabControl.SizeMode = TabSizeMode.Fixed; foreach (TabPage tab in tabControl.TabPages) { tab.Text = ""; } – marz Dec 08 '17 at 08:45
In my WinForms app, I was able to work around this by positioning the TabControl's y-coordinate outside the visible range of the form, so the tabs were effectively hidden. This example only works if the tabControl is near the top of the form, but you get the idea.
private void frmOptions_Load(object sender, EventArgs e)
{
tabControl1.Top = -23; //Only tabPage contents visible
}

- 399
- 3
- 13