170

How to hide TabPage from TabControl in WinForms 2.0?

Tom Smykowski
  • 25,487
  • 54
  • 159
  • 236
  • 2
    @tomaszs , you can try removing tab page Like TabPage page2 = tabControl1.TabPages[tpAdministration.Name ]; tabControl1.TabPages.Remove(page2); – faheem khan Apr 29 '13 at 16:46

22 Answers22

143

No, this doesn't exist. You have to remove the tab and re-add it when you want it. Or use a different (3rd-party) tab control.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • 3
    But RemoveByKey() + Add() is totally working – Vinko Vrsalovic Oct 03 '13 at 14:30
  • 3
    A frustration is that `RemoveByKey` then `Add` later upsets the order. – Colonel Panic Apr 07 '15 at 16:07
  • @VinkoVrsalovic that's what this answer essentially says... "remove the tab and re-add it" - it just doesn't give code for how to do it. Also, by basically saying this isn't "possible" it implies trying this will issues - one of which is the order of the tabs... – Code Jockey Aug 26 '15 at 20:13
  • But it is ok. You can quickly (on form load) copy the Tab object you want to be hidden to a static variable to wait until user want to be shown.Ten you just add it to the COntrols tab collection again. – TomeeNS Dec 18 '15 at 00:22
125

Code Snippet for Hiding a TabPage

private void HideTab1_Click(object sender, EventArgs e)
{
    tabControl1.TabPages.Remove(tabPage1);
}

Code Snippet for Showing a TabPage

private void ShowTab1_Click(object sender, EventArgs e)
{
    tabControl1.TabPages.Add(tabPage1);
}
musefan
  • 47,875
  • 21
  • 135
  • 185
moonshine
  • 1,339
  • 2
  • 9
  • 8
  • IN what WInForms version this does actually work? – Tom Smykowski Dec 29 '11 at 16:10
  • Only trouble with this is when, for example, you're trying to hide a menustrip that will be added to the MDI parent. Removing the tab unhooks all the events and merging from the menu. –  Jul 13 '12 at 00:02
  • 2
    Or optionally: `int idx = tabControl1.TabPages.IndexOf(tabPage1); tabControl1.TabPages.RemoveAt(idx);` – Jay Dec 03 '12 at 06:11
  • Worked perfectly, Jay! Thank you! – Jeagr Jan 26 '13 at 09:07
  • 2
    This will only work as expected for the last page. All other pages will move to the end when being shown. – Daniel Hilgarth Jun 19 '14 at 09:29
  • 4
    Your add is safer as `if (!tabControl1.Controls.Contains(tabPage1)) tabControl1.Controls.Add(tabPage1);` so it doesn't get added twice and get confused. – Jesse Chisholm Feb 13 '15 at 02:52
  • Only that this solution removes and adds the page back, not actually hiding it. This might be important to mention depending on the intended actions made to the page when it's not attached to the tab control. – Alex P. Jul 15 '22 at 09:53
56

I realize the question is old, and the accepted answer is old, but ...

At least in .NET 4.0 ...

To hide a tab:

tabControl.TabPages.Remove(tabPage);

To put it back:

tabControl.TabPages.Insert(index, tabPage);

TabPages works so much better than Controls for this.

Jesse Chisholm
  • 3,857
  • 1
  • 35
  • 29
32

Visiblity property has not been implemented on the Tabpages, and there is no Insert method also.

You need to manually insert and remove tab pages.

Here is a work around for the same.

http://www.dotnetspider.com/resources/18344-Hiding-Showing-Tabpages-Tabcontrol.aspx

amazedsaint
  • 7,642
  • 7
  • 54
  • 83
23

Variant 1

In order to avoid visual klikering you might need to use:

bindingSource.RaiseListChangeEvent = false 

or

myTabControl.RaiseSelectedIndexChanged = false

Remove a tab page:

myTabControl.Remove(myTabPage);

Add a tab page:

myTabControl.Add(myTabPage);

Insert a tab page at specific location:

myTabControl.Insert(2, myTabPage);

Do not forget to revers the changes:

bindingSource.RaiseListChangeEvent = true;

or

myTabControl.RaiseSelectedIndexChanged = true;

Variant 2

myTabPage.parent = null;
myTabPage.parent = myTabControl;
bluish
  • 26,356
  • 27
  • 122
  • 180
profimedica
  • 2,716
  • 31
  • 41
19

Solutions provided so far are way too complicated. Read the easiest solution at: http://www.codeproject.com/Questions/614157/How-to-Hide-TabControl-Headers

You could use this method to make them invisible at run time:

private void HideAllTabsOnTabControl(TabControl theTabControl)
{
  theTabControl.Appearance = TabAppearance.FlatButtons;
  theTabControl.ItemSize = new Size(0, 1);
  theTabControl.SizeMode = TabSizeMode.Fixed;
}
mas
  • 191
  • 1
  • 2
10

I combined the answer from @Jack Griffin and the one from @amazedsaint (the dotnetspider code snippet respectively) into a single TabControlHelper.

The TabControlHelper lets you:

  • Show / Hide all tab pages
  • Show / Hide single tab pages
  • Keep the original position of the tab pages
  • Swap tab pages

public class TabControlHelper
{
    private TabControl _tabControl;
    private List<KeyValuePair<TabPage, int>> _pagesIndexed;
    public TabControlHelper(TabControl tabControl)
    {
        _tabControl = tabControl;
        _pagesIndexed = new List<KeyValuePair<TabPage, int>>();

        for (int i = 0; i < tabControl.TabPages.Count; i++)
        {
            _pagesIndexed.Add(new KeyValuePair<TabPage, int> (tabControl.TabPages[i], i ));
        }
    }

    public void HideAllPages()
    {
        for (int i = 0; i < _pagesIndexed.Count; i++)
        {
            _tabControl.TabPages.Remove(_pagesIndexed[i].Key);
        }
    }

    public void ShowAllPages()
    {
        for (int i = 0; i < _pagesIndexed.Count; i++)
        {
            _tabControl.TabPages.Add(_pagesIndexed[i].Key);
        }
    }

    public void HidePage(TabPage tabpage)
    {
        if (!_tabControl.TabPages.Contains(tabpage)) return;
        _tabControl.TabPages.Remove(tabpage);
    }

    public void ShowPage(TabPage tabpage)
    {
        if (_tabControl.TabPages.Contains(tabpage)) return;
        InsertTabPage(GetTabPage(tabpage).Key, GetTabPage(tabpage).Value);
    }

    private void InsertTabPage(TabPage tabpage, int index)
    {
        if (index < 0 || index > _tabControl.TabCount)
            throw new ArgumentException("Index out of Range.");
        _tabControl.TabPages.Add(tabpage);
        if (index < _tabControl.TabCount - 1)
            do
            {
                SwapTabPages(tabpage, (_tabControl.TabPages[_tabControl.TabPages.IndexOf(tabpage) - 1]));
            }
            while (_tabControl.TabPages.IndexOf(tabpage) != index);
        _tabControl.SelectedTab = tabpage;
    }

    private void SwapTabPages(TabPage tabpage1, TabPage tabpage2)
    {
        if (_tabControl.TabPages.Contains(tabpage1) == false || _tabControl.TabPages.Contains(tabpage2) == false)
            throw new ArgumentException("TabPages must be in the TabControls TabPageCollection.");

        int Index1 = _tabControl.TabPages.IndexOf(tabpage1);
        int Index2 = _tabControl.TabPages.IndexOf(tabpage2);
        _tabControl.TabPages[Index1] = tabpage2;
        _tabControl.TabPages[Index2] = tabpage1;
    }

    private KeyValuePair<TabPage, int> GetTabPage(TabPage tabpage)
    {
        return _pagesIndexed.Where(p => p.Key == tabpage).First();
    }
}

Example on how to use it:

TabControl myTabControl = new TabControl();
TabControlHelper myHelper = new TabControlHelper(myTabControl);
myHelper.HideAllPages();
myHelper.ShowAllPages();
Bruno Bieri
  • 9,724
  • 11
  • 63
  • 92
6
private System.Windows.Forms.TabControl _tabControl;
private System.Windows.Forms.TabPage _tabPage1;
private System.Windows.Forms.TabPage _tabPage2;

...
// Initialise the controls
...

// "hides" tab page 2
_tabControl.TabPages.Remove(_tabPage2);

// "shows" tab page 2
// if the tab control does not contain tabpage2
if (! _tabControl.TabPages.Contains(_tabPage2))
{
    _tabControl.TabPages.Add(_tabPage2);
}
P. Sohm
  • 2,842
  • 2
  • 44
  • 77
4

Create a new empty class and past this inside it:

using System.Windows.Forms;

namespace ExtensionMethods
{
    public static class TabPageExtensions
    {

        public static bool IsVisible(this TabPage tabPage)
        {
            if (tabPage.Parent == null)
                return false;
            else if (tabPage.Parent.Contains(tabPage))
                return true;
            else
                return false;
        }

        public static void HidePage(this TabPage tabPage)
        {
            TabControl parent = (TabControl)tabPage.Parent;
            parent.TabPages.Remove(tabPage);
        }

        public static void ShowPageInTabControl(this TabPage tabPage,TabControl parent)
        {
            parent.TabPages.Add(tabPage);
        }
    }
}

2- Add reference to ExtensionMethods namespace in your form code:

using ExtensionMethods;

3- Now you can use yourTabPage.IsVisible(); to check its visibility, yourTabPage.HidePage(); to hide it, and yourTabPage.ShowPageInTabControl(parentTabControl); to show it.

Mhdali
  • 690
  • 7
  • 17
3

you can set the parent of the tabpage to null for hiding and to show just set tabpage parent to the tabcontrol

Abuleen
  • 453
  • 4
  • 8
1
    public static Action<Func<TabPage, bool>> GetTabHider(this TabControl container) {
        if (container == null) throw new ArgumentNullException("container");

        var orderedCache = new List<TabPage>();
        var orderedEnumerator = container.TabPages.GetEnumerator();
        while (orderedEnumerator.MoveNext()) {
            var current = orderedEnumerator.Current as TabPage;
            if (current != null) {
                orderedCache.Add(current);
            }
        }

        return (Func<TabPage, bool> where) => {
            if (where == null) throw new ArgumentNullException("where");

            container.TabPages.Clear();
            foreach (TabPage page in orderedCache) {
                if (where(page)) {
                    container.TabPages.Add(page);
                }
            }
        };
    }

Use it like this:

    var hider = this.TabContainer1.GetTabHider();
    hider((tab) => tab.Text != "tabPage1");
    hider((tab) => tab.Text != "tabpage2");

The original ordering of the tabs is kept in a List that is completely hidden inside the anonymous function. Keep a reference to the function instance and you retain your original tab order.

Rob
  • 517
  • 3
  • 10
1

+1 for microsoft :-) .
I managed to do it this way:
(it assumes you have a Next button that displays the next TabPage - tabSteps is the name of the Tab control)
At start up, save all the tabpages in a proper list.
When user presses Next button, remove all the TabPages in the tab control, then add that with the proper index:

int step = -1;
List<TabPage> savedTabPages;

private void FMain_Load(object sender, EventArgs e) {
    // save all tabpages in the list
    savedTabPages = new List<TabPage>();
    foreach (TabPage tp in tabSteps.TabPages) {
        savedTabPages.Add(tp);
    }
    SelectNextStep();
}

private void SelectNextStep() {
    step++;
    // remove all tabs
    for (int i = tabSteps.TabPages.Count - 1; i >= 0 ; i--) {
            tabSteps.TabPages.Remove(tabSteps.TabPages[i]);
    }

    // add required tab
    tabSteps.TabPages.Add(savedTabPages[step]);
}

private void btnNext_Click(object sender, EventArgs e) {
    SelectNextStep();
}

Update

public class TabControlHelper {
    private TabControl tc;
    private List<TabPage> pages;
    public TabControlHelper(TabControl tabControl) {
        tc = tabControl;
        pages = new List<TabPage>();
        foreach (TabPage p in tc.TabPages) {
            pages.Add(p);
        }
    }

    public void HideAllPages() {
        foreach(TabPage p in pages) {
            tc.TabPages.Remove(p);
        }
    }

    public void ShowAllPages() {
        foreach (TabPage p in pages) {
            tc.TabPages.Add(p);
        }
    }

    public void HidePage(TabPage tp) {
        tc.TabPages.Remove(tp);
    }        

    public void ShowPage(TabPage tp) {
        tc.TabPages.Add(tp);
    }
}  
Jimi
  • 29,621
  • 8
  • 43
  • 61
Jack Griffin
  • 1,228
  • 10
  • 17
1

Well, if you don't want to mess up existing code and just want to hide a tab, you could modify the compiler generated code to comment the line which adds the tab to the tabcontrol.

For example: The following line adds a tab named "readformatcardpage" to a Tabcontrol named "tabcontrol"

this.tabcontrol.Controls.Add(this.readformatcardpage);

The following will prevent addition of the tab to the tabcontrol

//this.tabcontrol.Controls.Add(this.readformatcardpage);

user720694
  • 2,035
  • 6
  • 35
  • 57
  • 2
    But, but, but ... as soon as you change anything on the form with Visual Studio designer, it will rewrite the .Designer.cs file and your modification will be lost. – RenniePet Jun 05 '13 at 23:13
  • @RenniePet I remember making extensive changes to the UI after commenting similar lines. It had no effect whatsoever on the tab that i had purposefully hidden. – user720694 Jun 08 '13 at 18:05
  • It is a tempory solution and works great. Will be useful to hide the tab this way and get exe file without the tab. Then uncomment to continue with your work – electricalbah Jul 23 '13 at 03:42
1
TabPage pageListe, pageDetay;
bool isDetay = false;

private void btnListeDetay_Click(object sender, EventArgs e)
{
    if (isDetay)
    {
        isDetay = false;
        tc.TabPages.Remove(tpKayit);
        tc.TabPages.Insert(0,pageListe);
    }
    else
    {
        tc.TabPages.Remove(tpListe);
        tc.TabPages.Insert(0,pageDetay);
        isDetay = true;
    }
}
Jimi
  • 29,621
  • 8
  • 43
  • 61
0

As a cheap work around, I've used a label to cover up the tabs I wanted to hide.

We can then use the visible prop of the label as a substitute. If anyone does go this route, don't forget to handle keyboard strokes or visibility events. You wouldn't want the left right cursor keys exposing the tab you're trying to hide.

  • 1
    How do you cope with resizing? I can imagine this is problematic, especially when the tab control is set to very small sizes. – Marcus Riemer Nov 06 '12 at 12:58
0

Not sure about "Winforms 2.0" but this is tried and proven:

http://www.mostthingsweb.com/2011/01/hiding-tab-headers-on-a-tabcontrol-in-c/

Jake
  • 11,273
  • 21
  • 90
  • 147
0

In WPF, it's pretty easy:

Assuming you've given the TabItem a name, e.g.,

<TabItem Header="Admin" Name="adminTab" Visibility="Hidden">
<!-- tab content -->
</TabItem>

You could have the following in the code behind the form:

 if (user.AccessLevel == AccessLevelEnum.Admin)
 {
     adminTab.Visibility = System.Windows.Visibility.Visible;
 }

It should be noted that a User object named user has been created with it's AccessLevel property set to one of the user-defined enum values of AccessLevelEnum... whatever; it's just a condition by which I decide to show the tab or not.

Jim Daehn
  • 196
  • 1
  • 7
  • 1
    Opps; sorry! My first response here at stackoverflow violated a basic principle: Read the question! I'm sorry, I didn't notice the Windows Forms part of the question; I gave a response related to WPF. My apologies... – Jim Daehn May 15 '13 at 15:41
0

I also had this question. tabPage.Visible is not implemented as stated earlier, which was a great help (+1). I found you can override the control and this will work. A bit of necroposting, but I thought to post my solution here for others...

    [System.ComponentModel.DesignerCategory("Code")]
public class MyTabPage : TabPage
{
    private TabControl _parent;
    private bool _isVisible;
    private int _index;
    public new bool Visible
    {
        get { return _isVisible; }
        set
        {
            if (_parent == null) _parent = this.Parent as TabControl;
            if (_parent == null) return;

            if (_index < 0) _index = _parent.TabPages.IndexOf(this);
            if (value && !_parent.TabPages.Contains(this))
            {
                if (_index > 0) _parent.TabPages.Insert(_index, this);
                else _parent.TabPages.Add(this);
            }
            else if (!value && _parent.TabPages.Contains(this)) _parent.TabPages.Remove(this);

            _isVisible = value;
            base.Visible = value;
        }
    }

    protected override void InitLayout()
    {
        base.InitLayout();
        _parent = Parent as TabControl;
    }
}
John S.
  • 1,937
  • 2
  • 18
  • 28
  • This has one problem: Workflow: Hide the second tab. Insert a new tab before its index. Show the second tab. It will now have moved. – Daniel Hilgarth Jun 19 '14 at 09:26
  • Eh, more like lean coding - we didn't need that feature, so we didn't add it ;) – John S. Jul 09 '14 at 20:40
  • Neat, but no design time support. – Darek Sep 12 '14 at 12:40
  • Yes there is. You have to compile it first and it will show up as a user control. Also, I suppress the double click designer with this line that you'll want to learn what it does and/or remove it: [System.ComponentModel.DesignerCategory("Code")] – John S. Sep 12 '14 at 15:56
0

I've used the same approach but the problem is that when tab page was removed from the tab control TabPages list, it is removed from the tab page Controls list also. And it is not disposed when form is disposed.

So if you have a lot of such "hidden" tab pages, you can get windows handle quota exceeded error and only application restart will fix it.

oleksa
  • 3,688
  • 1
  • 29
  • 54
0

If you are talking about AjaxTabControlExtender then set TabIndex of every tabs and set Visible property True/False according to your need.

myTab.Tabs[1].Visible=true/false;

-2
// inVisible
TabPage page2 = tabControl1.TabPages[0];
page2.Visible= false;
//Visible 
page2.Visible= true;
// disable
TabPage page2 = tabControl1.TabPages[0];
page2.Enabled = false;
// enable
page2.Enabled = true;
//Hide
tabCtrlTagInfo.TabPages(0).Hide()
tabCtrlTagInfo.TabPages(0).Show()

Just copy paste and try it,the above code has been tested in vs2010, it works.

Spontifixus
  • 6,570
  • 9
  • 45
  • 63
-2

Hide TabPage and Remove the Header:

this.tabPage1.Hide();
this.tabPage3.Hide();
this.tabPage5.Hide();
tabControl1.TabPages.Remove(tabPage1);
tabControl1.TabPages.Remove(tabPage3);
tabControl1.TabPages.Remove(tabPage5);

Show TabPage and Visible the Header:

tabControl1.TabPages.Insert(0,tabPage1);
tabControl1.TabPages.Insert(2, tabPage3);
tabControl1.TabPages.Insert(4, tabPage5);
this.tabPage1.Show();
this.tabPage3.Show();
this.tabPage5.Show();
tabControl1.SelectedTab = tabPage1;
Soma
  • 861
  • 2
  • 17
  • 32
ISB
  • 112
  • 7