[c#] How can I disable a tab inside a TabControl?

Is there a way to disable a tab in a TabControl?

This question is related to c# winforms tabcontrol

The answer is


Use:

 tabControl1.TabPages[1].Enabled = false;

By writing this code, the tab page won't be completely disabled (not being able to select), but its internal content will be disabled which I think satisfy your needs.


tabControl.TabPages.Remove(tabPage1);


I had to handle this a while back. I removed the Tab from the TabPages collection (I think that's it) and added it back in when the conditions changed. But that was only in Winforms where I could keep the tab around until I needed it again.


in C# 7.0, there is a new feature called Pattern Matching. You can disable all tabs via Type Pattern.

foreach (Control control in Controls)
{
    // the is expression tests the variable and 
    // assigned it to a new appropriate variable type
    if (control is TabControl tabs)
    {
        tabs.Enabled = false;
    }
}

I could not find an appropriate answer to the question. There looks to be no solution to disable the specific tab. What I did is to pass the specific tab to a variable and in SelectedIndexChanged event put it back to SelectedIndex:

//variable for your specific tab 
int _TAB = 0;

//here you specify your tab that you want to expose
_TAB = 1;
tabHolder.SelectedIndex = _TAB;

private void tabHolder_SelectedIndexChanged(object sender, EventArgs e)
{
    if (_TAB != 0) tabHolder.SelectedIndex = _TAB;
}

So, you don't actually disable the tab, but when another tab is clicked it always returns you to the selected tab.


MyTabControl.SelectedTab.Enabled = false;

Using events, and the properties of the tab control you can enable/disable what you want when you want. I used one bool that is available to all methods in the mdi child form class where the tabControl is being used.

Remember the selecting event fires every time any tab is clicked. For large numbers of tabs a "CASE" might be easier to use than a bunch of ifs.

public partial class Form2 : Form
    {
        bool formComplete = false;

        public Form2()
        {
            InitializeComponent();

        }

        private void button1_Click(object sender, EventArgs e)
        {


            formComplete = true;
            tabControl1.SelectTab(1);

        }

        private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
        {
            if (tabControl1.SelectedTab == tabControl1.TabPages[1])
            {

                tabControl1.Enabled = false;

                if (formComplete)
                {
                    MessageBox.Show("You will be taken to next tab");
                    tabControl1.SelectTab(1);

                }
                else
                {
                    MessageBox.Show("Try completing form first");
                    tabControl1.SelectTab(0);
                }
                tabControl1.Enabled = true;
            }
        }
    }

Use:

 tabControl1.TabPages[1].Enabled = false;

By writing this code, the tab page won't be completely disabled (not being able to select), but its internal content will be disabled which I think satisfy your needs.


You could register the "Selecting" event and cancel the navigation to the tab page:

private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
{
    if (e.TabPage == tabPage2)
        e.Cancel = true;
}

Another idea is to put all the controls on the tabpage in a Panel control and disable the panel! Smiley

You could also remove the tabpage from the tabControl1.TabPages collection. That would hide the tabpage.

Credits go to littleguru @ Channel 9.


Extending upon Cédric Guillemette answer, after you disable the Control:

((Control)this.tabPage).Enabled = false;

...you may then handle the TabControl's Selecting event as:

private void tabControl_Selecting(object sender, TabControlCancelEventArgs e)
{
    e.Cancel = !((Control)e.TabPage).Enabled;
}

Cast your TabPage to a Control, then set the Enabled property to false.

((Control)this.tabPage).Enabled = false;

Therefore, the tabpage's header will still be enabled but its contents will be disabled.


You could register the "Selecting" event and cancel the navigation to the tab page:

private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
{
    if (e.TabPage == tabPage2)
        e.Cancel = true;
}

Another idea is to put all the controls on the tabpage in a Panel control and disable the panel! Smiley

You could also remove the tabpage from the tabControl1.TabPages collection. That would hide the tabpage.

Credits go to littleguru @ Channel 9.


I've removed tab pages in the past to prevent the user from clicking them. This probably isn't the best solution though because they may need to see that the tab page exists.


In the form load event if we write this.tabpage.PageEnabled = false, the tabpage will be disabled.


MyTabControl.SelectedTab.Enabled = false;

The solution is very simple.

Remove/comment this line

this.tabControl.Controls.Add(this.YourTabName);

in IntializeComponent() method in MainForm.cs


This will remove the tab page, but you'll need to re-add it when you need it:

tabControl1.Controls.Remove(tabPage2);

If you are going to need it later, you might want to store it in a temporary tabpage before the remove and then re-add it when needed.


The only way is to catch the Selecting event and prevent a tab from being activated.


The most tricky way is to make its parent equals null (make the tab alone without parent):

 tabPage.Parent = null;

And when you want to return it back (will return it back at the end of pages collection) :

tabPage.Parent = tabControl;

And if you want to return it back in a specific location among the pages you can use :

tabControl.TabPages.Insert(indexLocationYouWant, tabPage);

The only way is to catch the Selecting event and prevent a tab from being activated.


You can simply use:

tabPage.Enabled = false;

This property is not shown, but it works without any problems.

You can program the Selecting event on TabControler to make it impossible to change to a non-editable tab:

private void tabControler_Selecting(object sender, TabControlCancelEventArgs e)
{
    if (e.TabPageIndex < 0) return;
    e.Cancel = !e.TabPage.Enabled;
}

Presumably, you want to see the tab in the tab control, but you want it to be "disabled" (i.e., greyed, and unselectable). There is no built-in support for this, but you can override the drawing mechanism to give the desired effect.

An example of how to do this is provided here.

The magic is in this snippet from the presented source, and in the DisableTab_DrawItem method:

this.tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
this.tabControl1.DrawItem += new DrawItemEventHandler( DisableTab_DrawItem );

Cast your TabPage to a Control, then set the Enabled property to false.

((Control)this.tabPage).Enabled = false;

Therefore, the tabpage's header will still be enabled but its contents will be disabled.


I could not find an appropriate answer to the question. There looks to be no solution to disable the specific tab. What I did is to pass the specific tab to a variable and in SelectedIndexChanged event put it back to SelectedIndex:

//variable for your specific tab 
int _TAB = 0;

//here you specify your tab that you want to expose
_TAB = 1;
tabHolder.SelectedIndex = _TAB;

private void tabHolder_SelectedIndexChanged(object sender, EventArgs e)
{
    if (_TAB != 0) tabHolder.SelectedIndex = _TAB;
}

So, you don't actually disable the tab, but when another tab is clicked it always returns you to the selected tab.


I've removed tab pages in the past to prevent the user from clicking them. This probably isn't the best solution though because they may need to see that the tab page exists.


This will remove the tab page, but you'll need to re-add it when you need it:

tabControl1.Controls.Remove(tabPage2);

If you are going to need it later, you might want to store it in a temporary tabpage before the remove and then re-add it when needed.


in C# 7.0, there is a new feature called Pattern Matching. You can disable all tabs via Type Pattern.

foreach (Control control in Controls)
{
    // the is expression tests the variable and 
    // assigned it to a new appropriate variable type
    if (control is TabControl tabs)
    {
        tabs.Enabled = false;
    }
}

This is an old question, but someone may benefit from my addition. I needed a TabControl that would show hidden tabs successively (after an action was performed on the current tab). So, I made a quick class to inherit from and called HideSuccessive() on Load:

public class RevealingTabControl : TabControl
{
    private Action _showNextRequested = delegate { };

    public void HideSuccessive()
    {
        var tabPages = this.TabPages.Cast<TabPage>().Skip(1);
        var queue = new ConcurrentQueue<TabPage>(tabPages);
        tabPages.ToList().ForEach(t => t.Parent = null);
        _showNextRequested = () =>
        {
            if (queue.TryDequeue(out TabPage tabPage))
                tabPage.Parent = this;
        };
    }

    public void ShowNext() => _showNextRequested();
}

The only way is to catch the Selecting event and prevent a tab from being activated.


Cast your TabPage to a Control, then set the Enabled property to false.

((Control)this.tabPage).Enabled = false;

Therefore, the tabpage's header will still be enabled but its contents will be disabled.


I've removed tab pages in the past to prevent the user from clicking them. This probably isn't the best solution though because they may need to see that the tab page exists.


You can do it through the tabpages: tabPage1.Hide(), tabPage2.Show() etc.


The only way is to catch the Selecting event and prevent a tab from being activated.


I've solved this problem like this: I've got 3 tabs and I want to keep user at the first tab if he didnt log in, so on the SelectingEvent of TabControl I wrote

if (condition) { TabControl.Deselect("2ndPage"); TabControl.Deselect("3dPage"); }

Cast your TabPage to a Control, then set the Enabled property to false.

((Control)this.tabPage).Enabled = false;

Therefore, the tabpage's header will still be enabled but its contents will be disabled.


The most tricky way is to make its parent equals null (make the tab alone without parent):

 tabPage.Parent = null;

And when you want to return it back (will return it back at the end of pages collection) :

tabPage.Parent = tabControl;

And if you want to return it back in a specific location among the pages you can use :

tabControl.TabPages.Insert(indexLocationYouWant, tabPage);

Using events, and the properties of the tab control you can enable/disable what you want when you want. I used one bool that is available to all methods in the mdi child form class where the tabControl is being used.

Remember the selecting event fires every time any tab is clicked. For large numbers of tabs a "CASE" might be easier to use than a bunch of ifs.

public partial class Form2 : Form
    {
        bool formComplete = false;

        public Form2()
        {
            InitializeComponent();

        }

        private void button1_Click(object sender, EventArgs e)
        {


            formComplete = true;
            tabControl1.SelectTab(1);

        }

        private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
        {
            if (tabControl1.SelectedTab == tabControl1.TabPages[1])
            {

                tabControl1.Enabled = false;

                if (formComplete)
                {
                    MessageBox.Show("You will be taken to next tab");
                    tabControl1.SelectTab(1);

                }
                else
                {
                    MessageBox.Show("Try completing form first");
                    tabControl1.SelectTab(0);
                }
                tabControl1.Enabled = true;
            }
        }
    }

I had to handle this a while back. I removed the Tab from the TabPages collection (I think that's it) and added it back in when the conditions changed. But that was only in Winforms where I could keep the tab around until I needed it again.


I've removed tab pages in the past to prevent the user from clicking them. This probably isn't the best solution though because they may need to see that the tab page exists.


Extending upon Cédric Guillemette answer, after you disable the Control:

((Control)this.tabPage).Enabled = false;

...you may then handle the TabControl's Selecting event as:

private void tabControl_Selecting(object sender, TabControlCancelEventArgs e)
{
    e.Cancel = !((Control)e.TabPage).Enabled;
}

The user cannot click on tabs to navigate, but they can use the two buttons (Next and Back). The user cannot continue to the next if the //conditions are no met.

private int currentTab = 0;

private void frmOneTimeEntry_Load(object sender, EventArgs e)
{
    tabMenu.Selecting += new TabControlCancelEventHandler(tabMenu_Selecting);
}

private void tabMenu_Selecting(object sender, TabControlCancelEventArgs e)
{
    tabMenu.SelectTab(currentTab);
}

private void btnNextStep_Click(object sender, EventArgs e)
{
    switch(tabMenu.SelectedIndex)
    {
        case 0:
            //if conditions met GoTo
        case 2:
            //if conditions met GoTo
        case n:
            //if conditions met GoTo
    {
    CanLeaveTab:
    currentTab++;
    tabMenu.SelectTab(tabMenu.SelectedIndex + 1);
    if (tabMenu.SelectedIndex == 3)
        btnNextStep.Enabled = false;
    if (btnBackStep.Enabled == false)
        btnBackStep.Enabled = true;

    CannotLeaveTab:
        ;
}

private void btnBackStep_Click(object sender, EventArgs e)
{
    currentTab--;
    tabMenu.SelectTab(tabMenu.SelectedIndex - 1);
    if (tabMenu.SelectedIndex == 0)
        btnBackStep.Enabled = false;
    if (btnNextStep.Enabled == false)
        btnNextStep.Enabled = true;
}

Presumably, you want to see the tab in the tab control, but you want it to be "disabled" (i.e., greyed, and unselectable). There is no built-in support for this, but you can override the drawing mechanism to give the desired effect.

An example of how to do this is provided here.

The magic is in this snippet from the presented source, and in the DisableTab_DrawItem method:

this.tabControl1.DrawMode = TabDrawMode.OwnerDrawFixed;
this.tabControl1.DrawItem += new DrawItemEventHandler( DisableTab_DrawItem );

I had to handle this a while back. I removed the Tab from the TabPages collection (I think that's it) and added it back in when the conditions changed. But that was only in Winforms where I could keep the tab around until I needed it again.


Assume that you have these controls:

TabControl with name tcExemple.

TabPages with names tpEx1 and tpEx2.

Try it:

Set DrawMode of your TabPage to OwnerDrawFixed; After InitializeComponent(), make sure that tpEx2 is not enable by adding this code:

((Control)tcExemple.TabPages["tpEx2").Enabled = false;

Add to Selection tcExemple event the code below:

private void tcExemple_Selecting(object sender, TabControlCancelEventArgs e)
    {
        if (!((Control)e.TabPage).Enabled)
        {
            e.Cancel = true;
        }
    }

Attach to DrawItem event of tcExemple this code:

private void tcExemple_DrawItem(object sender, DrawItemEventArgs e)
    {
        TabPage page = tcExemple.TabPages[e.Index];
        if (!((Control)page).Enabled)
        {
            using (SolidBrush brush = new SolidBrush(SystemColors.GrayText))
            {
                e.Graphics.DrawString(page.Text, page.Font, brush, e.Bounds);
            }
        }
        else
        {
            using (SolidBrush brush = new SolidBrush(page.ForeColor))
            {
                e.Graphics.DrawString(page.Text, page.Font, brush, e.Bounds);
            }
        }
    }

It will make the second tab non-clickable.


I had to handle this a while back. I removed the Tab from the TabPages collection (I think that's it) and added it back in when the conditions changed. But that was only in Winforms where I could keep the tab around until I needed it again.


You can do it through the tabpages: tabPage1.Hide(), tabPage2.Show() etc.


This is an old question, but someone may benefit from my addition. I needed a TabControl that would show hidden tabs successively (after an action was performed on the current tab). So, I made a quick class to inherit from and called HideSuccessive() on Load:

public class RevealingTabControl : TabControl
{
    private Action _showNextRequested = delegate { };

    public void HideSuccessive()
    {
        var tabPages = this.TabPages.Cast<TabPage>().Skip(1);
        var queue = new ConcurrentQueue<TabPage>(tabPages);
        tabPages.ToList().ForEach(t => t.Parent = null);
        _showNextRequested = () =>
        {
            if (queue.TryDequeue(out TabPage tabPage))
                tabPage.Parent = this;
        };
    }

    public void ShowNext() => _showNextRequested();
}

You could register the "Selecting" event and cancel the navigation to the tab page:

private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
{
    if (e.TabPage == tabPage2)
        e.Cancel = true;
}

Another idea is to put all the controls on the tabpage in a Panel control and disable the panel! Smiley

You could also remove the tabpage from the tabControl1.TabPages collection. That would hide the tabpage.

Credits go to littleguru @ Channel 9.


tabControl.TabPages.Remove(tabPage1);


The solution is very simple.

Remove/comment this line

this.tabControl.Controls.Add(this.YourTabName);

in IntializeComponent() method in MainForm.cs


I've solved this problem like this: I've got 3 tabs and I want to keep user at the first tab if he didnt log in, so on the SelectingEvent of TabControl I wrote

if (condition) { TabControl.Deselect("2ndPage"); TabControl.Deselect("3dPage"); }

You can simply use:

tabPage.Enabled = false;

This property is not shown, but it works without any problems.

You can program the Selecting event on TabControler to make it impossible to change to a non-editable tab:

private void tabControler_Selecting(object sender, TabControlCancelEventArgs e)
{
    if (e.TabPageIndex < 0) return;
    e.Cancel = !e.TabPage.Enabled;
}

In the form load event if we write this.tabpage.PageEnabled = false, the tabpage will be disabled.


Assume that you have these controls:

TabControl with name tcExemple.

TabPages with names tpEx1 and tpEx2.

Try it:

Set DrawMode of your TabPage to OwnerDrawFixed; After InitializeComponent(), make sure that tpEx2 is not enable by adding this code:

((Control)tcExemple.TabPages["tpEx2").Enabled = false;

Add to Selection tcExemple event the code below:

private void tcExemple_Selecting(object sender, TabControlCancelEventArgs e)
    {
        if (!((Control)e.TabPage).Enabled)
        {
            e.Cancel = true;
        }
    }

Attach to DrawItem event of tcExemple this code:

private void tcExemple_DrawItem(object sender, DrawItemEventArgs e)
    {
        TabPage page = tcExemple.TabPages[e.Index];
        if (!((Control)page).Enabled)
        {
            using (SolidBrush brush = new SolidBrush(SystemColors.GrayText))
            {
                e.Graphics.DrawString(page.Text, page.Font, brush, e.Bounds);
            }
        }
        else
        {
            using (SolidBrush brush = new SolidBrush(page.ForeColor))
            {
                e.Graphics.DrawString(page.Text, page.Font, brush, e.Bounds);
            }
        }
    }

It will make the second tab non-clickable.


The user cannot click on tabs to navigate, but they can use the two buttons (Next and Back). The user cannot continue to the next if the //conditions are no met.

private int currentTab = 0;

private void frmOneTimeEntry_Load(object sender, EventArgs e)
{
    tabMenu.Selecting += new TabControlCancelEventHandler(tabMenu_Selecting);
}

private void tabMenu_Selecting(object sender, TabControlCancelEventArgs e)
{
    tabMenu.SelectTab(currentTab);
}

private void btnNextStep_Click(object sender, EventArgs e)
{
    switch(tabMenu.SelectedIndex)
    {
        case 0:
            //if conditions met GoTo
        case 2:
            //if conditions met GoTo
        case n:
            //if conditions met GoTo
    {
    CanLeaveTab:
    currentTab++;
    tabMenu.SelectTab(tabMenu.SelectedIndex + 1);
    if (tabMenu.SelectedIndex == 3)
        btnNextStep.Enabled = false;
    if (btnBackStep.Enabled == false)
        btnBackStep.Enabled = true;

    CannotLeaveTab:
        ;
}

private void btnBackStep_Click(object sender, EventArgs e)
{
    currentTab--;
    tabMenu.SelectTab(tabMenu.SelectedIndex - 1);
    if (tabMenu.SelectedIndex == 0)
        btnBackStep.Enabled = false;
    if (btnNextStep.Enabled == false)
        btnNextStep.Enabled = true;
}