繁体   English   中英

如何禁用 TabControl 中的选项卡?

[英]How can I disable a tab inside a TabControl?

有没有办法禁用TabControl中的选项卡?

将 TabPage 转换为 Control,然后将 Enabled 属性设置为 false。

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

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

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

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

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

您可以简单地使用:

tabPage.Enabled = false;

此属性未显示,但它可以正常工作。

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

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

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

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

另一个想法是将标签页上的所有控件放在一个面板控件中并禁用面板! 笑脸

您还可以从 tabControl1.TabPages 集合中删除标签页。 这将隐藏标签页。

学分转到littleguru@第 9 频道

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

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

神奇之处在于来自提供的源代码的这个片段,以及 DisableTab_DrawItem 方法:

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

在禁用Control后,扩展 Cédric Guillemette 的回答:

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

...然后您可以将TabControlSelecting事件处理为:

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

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

tabControl1.Controls.Remove(tabPage2);

如果您以后需要它,您可能希望在删除之前将其存储在一个临时标签页中,然后在需要时重新添加它。

唯一的方法是捕获Selecting事件并防止选项卡被激活。

最棘手的方法是使其父项等于 null(使选项卡单独没有父项):

 tabPage.Parent = null;

当您想返回它时(将在页面集合结束时返回):

tabPage.Parent = tabControl;

如果您想将其返回到页面中的特定位置,您可以使用:

tabControl.TabPages.Insert(indexLocationYouWant, tabPage);

不久前我不得不处理这个问题。 我从 TabPages 集合中删除了 Tab(我认为就是这样),并在条件发生变化时将其重新添加。 但这只是在 Winforms 中我可以保留标签直到我再次需要它。

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

请记住,每次单击任何选项卡时都会触发选择事件。 对于大量选项卡,“CASE”可能比一堆 if 更容易使用。

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

你可以通过标签页来实现:tabPage1.Hide()、tabPage2.Show() 等。

用户无法单击选项卡进行导航,但他们可以使用两个按钮( 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;
}

我已经这样解决了这个问题:我有 3 个选项卡,如果他没有登录,我想将用户保留在第一个选项卡上,所以在我写的 TabControl 的 SelectingEvent 上

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

tabControl.TabPages.Remove(tabPage1);

针对Vb.Net的rfnodulator答案:

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

我过去删除了标签页以防止用户点击它们。 这可能不是最好的解决方案,因为他们可能需要查看标签页是否存在。

这是一个老问题,但有人可能会从我的补充中受益。 我需要一个 TabControl 来连续显示隐藏的选项卡(在当前选项卡上执行操作之后)。 因此,我创建了一个快速类来继承并在加载时调用 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();
}

XtraTabPage.PageEnabled 属性允许您禁用某些页面。

这是我实施的解决方案:

   private void switchTapPage(TabPage tabPage)
    {
        
        foreach(TabPage page in tabControl1.TabPages)
        {
            tabControl1.TabPages.Remove(page);
        }

        tabControl1.TabPages.Add(tabPage);
    }

基本上,我只是调用此方法发送我当前需要显示的 tabPage,该方法将删除 tabControl 上的所有 tabPage,然后它只会添加我发送的那个。

因此 tabHeaders 的 rest 将不会显示并且它们将不可访问,因为它们甚至不存在于 tabControl 中。

我从@storm.net的回答中得到了这个想法。

在表单加载事件中如果我们写this.tabpage.PageEnabled = false ,tabpage 将被禁用。

假设您有以下控件:

名称为 tcExemple 的 TabControl。

名称为 tpEx1 和 tpEx2 的 TabPage。

尝试一下:

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

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

将以下代码添加到选择 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);
            }
        }
    }

它将使第二个选项卡不可点击。

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

因此,您实际上并未禁用该选项卡,但是当单击另一个选项卡时,它始终会返回到所选选项卡。

在 C# 7.0 中,有一个名为Pattern Matching的新功能。 您可以通过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;
    }
}

用:

 tabControl1.TabPages[1].Enabled = false;

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

解决方法很简单。

删除/注释此行

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

在 MainForm.cs 的 InitializeComponent() 方法中

MyTabControl.SelectedTab.Enabled = false;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM