如何禁用TabControl内的选项卡?


Answers:


71

TabPage的类隐藏Enabled属性。这是故意的,因为它存在一个尴尬的UI设计问题。基本问题是禁用页面不会同时禁用选项卡。并且,如果尝试通过使用Selecting事件禁用选项卡来解决此问题,则当TabControl只有一页时,它将不起作用。

如果您不关心这些可用性问题,那么请记住,该属性仍然有效,它只是对IntelliSense隐藏。如果FUD不舒服,则只需执行以下操作:

public static void EnableTab(TabPage page, bool enable) {
    foreach (Control ctl in page.Controls) ctl.Enabled = enable;
}

3
我想知道不允许切换制表符可见性的背后故事是什么
Shekhar,2015年

91

将您的TabPage强制转换为控件,然后将Enabled属性设置为false。

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

因此,选项卡页的标题仍将启用,但其内容将被禁用。


3
我认为这错过了禁用选项卡本身的意义。用户不应选择它并查看其内容。
ThunderGr 2012年

3
那可能是您的用例,但我认为如果由于某些权限该选项卡需要只读,则它很有用。
塞德里克Guillemette

9
为什么需要向下转换TabPage进行控制?由于多态性,我们可以从TabPage调用Enabled属性。
Eldar Agalarov

1
不确定是否曾经有所不同,但今天完全是胡说八道。69个提出错误的支持者。哎哟..
TAW

1
@TaW这个问题专门简洁地回答了这个问题。“有什么方法可以禁用tabcontrol中的选项卡吗?” 他们不问如何隐藏标签。右边的69个支持者... 1个评论者未按错误的理解。
uch

70

您可以简单地使用:

tabPage.Enabled = false;

该属性未显示,但可以正常使用。

您可以对Selecting事件进行编程,TabControler以使其无法更改为不可编辑的标签:

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

3
Visible尽管这在我测试时似乎并没有任何视觉效果,但这似乎也确实适用于该属性。
Alfie 2013年

@Alfie,因为TabPage继承自以下层次结构:“控制”>“ ScrollableControl”>“面板”>“ TabPage”,“启用”,“可见”等行为是多态的。
尤达大师

49

您可以注册“正在选择”事件并取消导航到标签页:

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

另一个想法是将所有控件放在面板控件的选项卡页上,然后禁用面板!笑脸

您也可以从tabControl1.TabPages集合中删除选项卡页。那会隐藏标签页。

致谢@ 9频道的littleguru


更完整的帖子,我应该发布的:)
Martijn Laarman

这是一个血腥的绝妙解决方案!!
Cornelius

13

大概是,您希望在选项卡控件中看到该选项卡,但是希望它被“禁用”(即,灰色且不可选择)。对此没有内置支持,但是您可以覆盖绘图机制以提供所需的效果。

这里提供了如何执行此操作的示例。

所显示的源代码中的这段代码以及DisableTab_DrawItem方法中的妙处在于:

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

1
示例链接现在似乎已失效。
Narthring

1
@Narthring-谢谢,我已将链接替换为可用的链接。
斯图尔特2012年

2
@Narthring又死了。
Sukasa 2014年

这是对该问题的“真实”答案。记录了Waybackmachine的无效链接:[ web.archive.org/web/20131102065816/http://…
Joe Uhren 2015年

此答案的一项改进...向每个选项卡添加EnabledChanged事件处理程序,并在选项卡控件上使事件处理程序调用Invalidate()。这样,文本颜色将自动更新。
ulatekh

12

在禁用以下功能后,扩展CédricGuillemette的答案Control

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

...您可以通过以下方式处理TabControlSelecting事件:

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

8

这将删除标签页,但是您需要在需要时重新添加它:

tabControl1.Controls.Remove(tabPage2);

如果以后要使用它,可能要在删除之前将其存储在一个临时选项卡中,然后在需要时重新添加它。


我认为,当您希望检查表单的Load事件时,如果用户有资格访问此选项卡,或者如果没有,则将其完全删除,则它非常适合。
ThunderGr 2012年


2

最棘手的方法是使其父级等于null(使制表符不带父级):

 tabPage.Parent = null;

而当您想将其退回时(将在页面集合的末尾将其退回):

tabPage.Parent = tabControl;

如果要在页面中的特定位置返回它,可以使用:

tabControl.TabPages.Insert(indexLocationYouWant, tabPage);

1
它的工作很好!:)..我有一个问题。当我们将其返回给tabcontrol时,将添加最终索引。从初始阶段起,我们如何在同一索引处添加标签页。
User6667769

1
如果要将其返回到所需的位置(而不是末尾),请使用:tabControl.TabPages.Insert(indexLocationYouWant,tabPage);
Amr Ashraf

1
感谢您的答复@Amr Ashraf
User6667769'Aug

1

我不得不前一段时间处理这个。我从TabPages集合中删除了Tab(我想就是这样),并在条件发生变化时又将其重新添加了。但是,只有在Winforms中,我才能保留该选项卡,直到再次需要它为止。


1

您可以通过以下标签页进行操作:tabPage1.Hide(),tabPage2.Show()等。


2
我在带有.net Compact Framework 3.5的Windows CE 6.0中使用了它,并且它正在工作。问题不提供有关该平台的任何线索。Web,台式机或移动设备在哪里需要?
aldebaran


0

过去,我已经删除了标签页,以防止用户单击它们。但是,这可能不是最佳解决方案,因为他们可能需要查看选项卡页是否存在。


0

使用事件和选项卡控件的属性,可以在需要时启用/禁用所需的内容。我使用了一个布尔值,该布尔值可用于正在使用tabControl的mdi子窗体类中的所有方法。

请记住,每次单击任何选项卡时都会触发选择事件。对于大量选项卡,“ CASE”可能比一堆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;
            }
        }
    }

0

我已经解决了这样的问题:我有3个标签,如果他没有登录,我希望将用户保留在第一个标签中,因此我写了TabControl的SelectingEvent

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

0

用户无法单击选项卡进行导航,但可以使用两个按钮(NextBack)。如果不符合//条件,则用户无法继续下一个。

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;
}

0

Vb.Net的rfnodulator答案:

Private Sub TabControl1_Selecting(sender As Object, e As TabControlCancelEventArgs) Handles TabControl1.Selecting
        e.Cancel = Not e.TabPage.Enabled
End Sub

0

假设您具有以下控件:

名为tcExemple的TabControl。

名为tpEx1和tpEx2的TabPage。

尝试一下:

将TabPage的DrawMode设置为OwnerDrawFixed; 在InitializeComponent()之后,通过添加以下代码来确保未启用tpEx2:

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

将以下代码添加到Selection tcExemple事件中:

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

将以下代码附加到tc的DrawItem事件上:

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);
            }
        }
    }

这将使第二个选项卡不可单击。


0

这是一个老问题,但是有人可能会从我的加入中受益。我需要一个TabControl,它将连续显示隐藏的选项卡(在当前选项卡上执行操作之后)。因此,我做了一个快速的类来继承并在Load上调用HideSuccessive():

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();
}

-1

如果我们写表单加载事件this.tabpage.PageEnabled = false,则选项卡页将被禁用。


无法看到该物业
约翰

请检查是否在表单的load事件中尝试过?
新的

刚刚加倍检查。看不到。
约翰

请检查您是否使用过此方法:private void XtraForm1_Load(object sender,EventArgs e){this.xtraTabPage1.PageEnabled = false; } XtraForm1是DevExpress XtraForm,而选项卡页面xtraTabPage是DevExpress XtraTabpage
New

您为什么在原始答案中没有说任何关于DevExpress的信息?
约翰

-1

使用:

 tabControl1.TabPages[1].Enabled = false;

通过编写此代码,标签页不会被完全禁用(无法选择),但是其内部内容将被禁用,我认为这满足您的需求。


-1

解决方案非常简单。

删除/注释此行

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

在MainForm.cs中的IntializeComponent()方法中


-1

我找不到这个问题的适当答案。似乎没有解决方案来禁用特定选项卡。我所做的是将特定的选项卡传递给变量,并SelectedIndexChanged最终将其放回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;
}

因此,您实际上并没有禁用该选项卡,但是当单击另一个选项卡时,它总是使您返回到选定的选项卡。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.