如何从 TabControl 隐藏 TabPage [重复]

Posted

技术标签:

【中文标题】如何从 TabControl 隐藏 TabPage [重复]【英文标题】:How to hide TabPage from TabControl [duplicate] 【发布时间】:2010-10-07 20:16:01 【问题描述】:

如何在 WinForms 2.0 中从 TabControl 中隐藏 TabPage?

【问题讨论】:

@tomaszs ,您可以尝试删除标签页 Like TabPage page2 = tabControl1.TabPages[tpAdministration.Name ]; tabControl1.TabPages.Remove(page2); 【参考方案1】:

不,这不存在。您必须删除选项卡并在需要时重新添加它。或使用不同的(第 3 方)选项卡控件。

【讨论】:

但是 RemoveByKey() + Add() 完全可以工作 令人沮丧的是RemoveByKey 然后Add 打乱了订单。 @VinkoVrsalovic 这就是这个答案本质上所说的......“删除标签并重新添加它” - 它只是没有给出如何做的代码。此外,基本上说这不是“可能的”,这意味着尝试这将问题 - 其中之一是选项卡的顺序...... 不过没关系。您可以快速(在表单加载时)将您想要隐藏的 Tab 对象复制到一个静态变量中,以等待用户想要显示。十您只需将其再次添加到 COntrols 选项卡集合中。【参考方案2】:

隐藏标签页的代码片段

private void HideTab1_Click(object sender, EventArgs e)

    tabControl1.TabPages.Remove(tabPage1);

显示标签页的代码片段

private void ShowTab1_Click(object sender, EventArgs e)

    tabControl1.TabPages.Add(tabPage1);

【讨论】:

在哪个 WInForms 版本中这确实有效? 唯一的问题是,例如,当您试图隐藏将添加到 MDI 父级的菜单条时。删除选项卡会取消所有事件并从菜单中合并。 或可选:int idx = tabControl1.TabPages.IndexOf(tabPage1); tabControl1.TabPages.RemoveAt(idx); 这只会在最后一页按预期工作。显示时,所有其他页面将移至末尾。 您的添加与if (!tabControl1.Controls.Contains(tabPage1)) tabControl1.Controls.Add(tabPage1); 一样更安全,因此不会被添加两次而感到困惑。【参考方案3】:

我意识到这个问题很老,接受的答案也很老,但是......

至少在 .NET 4.0 ...

隐藏标签:

tabControl.TabPages.Remove(tabPage);

把它放回去:

tabControl.TabPages.Insert(index, tabPage);

TabPages 在这方面的效果比Controls 好得多。

【讨论】:

如果需要重新插入标签页,请添加以下代码 IntPtr h = this.tabControl1.Handle; 这不是和***.com/a/8602869/3195477一样吗? @DaveInCaz 是的,几乎一样。 Add 总是把他的新标签放在右边,Insert 让你选择它的位置。【参考方案4】:

标签页上没有实现Visiblity属性,也没有Insert方法。

您需要手动插入和删除标签页。

这里有一个解决方法。

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

【讨论】:

【参考方案5】:

变体 1

为了避免视觉上的 klikering,您可能需要使用:

bindingSource.RaiseListChangeEvent = false 

myTabControl.RaiseSelectedIndexChanged = false

删除标签页:

myTabControl.Remove(myTabPage);

添加标签页:

myTabControl.Add(myTabPage);

在特定位置插入标签页:

myTabControl.Insert(2, myTabPage);

不要忘记撤消更改:

bindingSource.RaiseListChangeEvent = true;

myTabControl.RaiseSelectedIndexChanged = true;

变体 2

myTabPage.parent = null;
myTabPage.parent = myTabControl;

【讨论】:

变体 2 - 完美 tabPage1.Parent = myBoolVariable ? tabControl1 : null; Variant2 很好,但是当您恢复父标签页时,标签页将被附加到列表的末尾而不是其先前的位置。 System.Windows.Forms.TabControl 似乎没有定义 RaiseSelectedIndexChanged 是的,变体 2 更清晰。【参考方案6】:

目前提供的解决方案太复杂了。 阅读最简单的解决方案: http://www.codeproject.com/Questions/614157/How-to-Hide-TabControl-Headers

您可以使用此方法使它们在运行时不可见:

private void HideAllTabsOnTabControl(TabControl theTabControl)

  theTabControl.Appearance = TabAppearance.FlatButtons;
  theTabControl.ItemSize = new Size(0, 1);
  theTabControl.SizeMode = TabSizeMode.Fixed;

【讨论】:

【参考方案7】:

我将@Jack Griffin 的答案和@amazedsaint (the dotnetspider code snippet respectively) 的答案合并为一个TabControlHelper

TabControlHelper 可让您:

显示/隐藏所有标签页 显示/隐藏单个标签页 保留标签页的原始位置 交换标签页
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();
    

【讨论】:

要按名称访问标签页,您可以使用public TabPage GetTabPage(string tabName) =&gt; _tabControl.TabPages.Cast&lt;TabPage&gt;().Where(x =&gt; x.Name == tabName).First(); 感谢您的评论。您是否建议添加这样的方法?【参考方案8】:
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);

【讨论】:

【参考方案9】:

创建一个新的空类并在其中过去:

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- 在表单代码中添加对 ExtensionMethods 命名空间的引用:

using ExtensionMethods;

3- 现在您可以使用 yourTabPage.IsVisible(); 检查其可见性,使用 yourTabPage.HidePage(); 隐藏它,并使用 yourTabPage.ShowPageInTabControl(parentTabControl); 显示它。

【讨论】:

这只会在最后一页按预期工作。显示时,所有其他页面将移至末尾。【参考方案10】:

您可以将标签页的父级设置为 null 以进行隐藏 并显示将标签页父级设置为标签控件

【讨论】:

【参考方案11】:
    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);
                
            
        ;
    

像这样使用它:

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

选项卡的原始顺序保存在一个完全隐藏在匿名函数中的列表中。保留对函数实例的引用,并保留原来的 Tab 键顺序。

【讨论】:

为了展示它们,hider((tab) =&gt; tab.Text != null); -- 我喜欢它!【参考方案12】:

好吧,如果您不想弄乱现有代码而只想隐藏选项卡,则可以修改编译器生成的代码以注释将选项卡添加到选项卡控件的行。

例如: 以下行将名为“readformatcardpage”的选项卡添加到名为“tabcontrol”的 Tabcontrol

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

以下将阻止将选项卡添加到选项卡控件

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

【讨论】:

但是,但是,但是...一旦您使用 Visual Studio 设计器更改表单上的任何内容,它将重写 .Designer.cs 文件,您的修改将丢失。 @RenniePet 我记得在评论了类似的行之后对 UI 进行了广泛的更改。它对我故意隐藏的标签没有任何影响。 这是一个临时解决方案,效果很好。以这种方式隐藏选项卡并在没有选项卡的情况下获取 exe 文件将很有用。然后取消注释以继续您的工作【参考方案13】:

+1 微软 :-) . 我设法做到了: (假设您有一个显示下一个 TabPage 的 Next 按钮 - tabSteps 是 Tab 控件的名称) 启动时,将所有标签页保存在适当的列表中。 当用户按下Next 按钮时,删除选项卡控件中的所有TabPages,然后使用适当的索引添加:

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

更新

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

【讨论】:

【参考方案14】:
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;
    

【讨论】:

【参考方案15】:

作为一种廉价的解决方法,我使用了一个标签来掩盖我想隐藏的标签。

然后我们可以使用标签的可见属性作为替代。如果有人确实走这条路,请不要忘记处理键盘敲击或可见性事件。您不希望左右光标键暴露您要隐藏的选项卡。

【讨论】:

您如何应对大小调整?我可以想象这是有问题的,特别是当标签控制设置为非常小的尺寸时。 span> 【参考方案16】:

不确定“Winforms 2.0”,但这是经过尝试和证明的:

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

【讨论】:

【参考方案17】:

在 WPF 中,这很容易:

假设您已为 TabItem 命名,例如,

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

您可以在表单后面的代码中包含以下内容:

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

应该注意的是,一个名为userUser 对象已创建,它的AccessLevel 属性设置为AccessLevelEnum 的用户定义枚举值之一......无论如何;这只是我决定是否显示标签的条件。

【讨论】:

奥普斯;对不起!我在 *** 的第一个回复违反了一个基本原则:阅读问题!抱歉,我没有注意到问题的 Windows 窗体部分;我给出了与 WPF 相关的回复。抱歉……【参考方案18】:

我也有这个问题。 tabPage.Visible 没有如前所述实现,这是一个很大的帮助(+1)。我发现您可以覆盖控件,这将起作用。有点 necroposting,但我想在这里为其他人发布我的解决方案......

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

【讨论】:

这有一个问题:工作流程:隐藏第二个选项卡。在其索引之前插入一个新选项卡。显示第二个选项卡。它现在已经移动了。 嗯,更像精益编码——我们不需要那个功能,所以我们没有添加它;) 简洁,但不支持设计时。 是的。您必须先编译它,它将显示为用户控件。另外,我用这一行禁止双击设计器,您将想了解它的作用和/或删除它:[System.ComponentModel.DesignerCategory("Code")]【参考方案19】:

我使用了相同的方法,但问题是当标签页从标签页控件 TabPages 列表中删除时,它也会从标签页控件列表中删除。并且在处理表单时不处理它。

所以如果你有很多这样的“隐藏”标签页,你可以get windows handle quota exceeded error 并且只有应用程序重启才能解决它。

【讨论】:

【参考方案20】:

如果你在谈论 AjaxTabControlExtender 然后设置每个选项卡的 TabIndex 并根据需要设置 Visible 属性 True/False。

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

【讨论】:

【参考方案21】:
// 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()

复制粘贴试试看,上面的代码已经在vs2010中测试过了,可以的。

【讨论】:

我已经检查了这段代码。它没有用。 TabPage控件中没有Visible属性【参考方案22】:

隐藏 TabPage 并移除页眉:

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

显示 TabPage 并显示标题:

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:你是怎么改代码的?你能解释一下吗? 查看编辑?很清楚。

以上是关于如何从 TabControl 隐藏 TabPage [重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何设计没有 TabControl 的 TabPage?

如何清除嵌套在 TabControl、TabPage 和 2 个面板中的文本框?

C# WinForm怎么用程序切换tabcontrol?

winform中tabControl的标题隐藏

以编程方式选择 TabControl 中的现有 TabPage 会显示一个空白页

TabControl TabPage添加关闭按钮