43

我正在尝试根据用户选择显示或隐藏标签页。如果用户选择性别为男性,则应在标签页“男性”中显示男性表单,如果用户选择女性,则应在下一个选项卡“女性”中显示类似的下一个表单

我尝试使用

tabControl1.TabPages.Remove(...)

tabControl1.TabPages.Add(...)

它添加和删除标签页,但这样做也会失去我对标签页的控制......我看不到它们。这里有什么问题?

4

20 回答 20

45

我认为答案要容易得多。

要隐藏选项卡,您可以使用您已经尝试过的方式或处理 TabPage 本身。

TabControl1.TabPages.Remove(TabPage1) 'Could be male
TabControl1.TabPages.Remove(TabPage2) 'Could be female

阿苏

删除 TabPage 不会破坏它及其上的控件。要再次显示相应的选项卡,只需使用以下代码

TabControl1.TabPages.Insert(0, TabPage1) 'Show male
TabControl1.TabPages.Insert(1, TabPage2) 'Show female
于 2012-10-26T12:08:27.680 回答
38

您可以从 TabControl.TabPages 集合中删除标签页并将其存储在列表中。例如:

    private List<TabPage> hiddenPages = new List<TabPage>();

    private void EnablePage(TabPage page, bool enable) {
        if (enable) {
            tabControl1.TabPages.Add(page);
            hiddenPages.Remove(page);
        }
        else {
            tabControl1.TabPages.Remove(page);
            hiddenPages.Add(page);
        }
    }

    protected override void OnFormClosed(FormClosedEventArgs e) {
        foreach (var page in hiddenPages) page.Dispose();
        base.OnFormClosed(e);
    }
于 2010-07-29T17:48:49.513 回答
7

改进 Hans Passant 的好解决方案我决定根据他的解决方案编写一个扩展方法,并添加其他东西。令我惊讶的是,即使在 .NET 4 中,这个基本功能也没有得到修复。

  • 将其实现为可以以更透明的方式重用的扩展方法
  • 清理方法只清理正在处理/清理的控件的页面。
  • 只要有可能,标签页就会恢复到相同的位置。如果您隐藏/显示多个标签页,这并不总是可能的。
  • 它会进行一些错误和参数检查
  • 为了使它不可见,它会找到它的父级。当使其可见时,必须给出它,因为当标签页被删除时,父属性为空。


public static class TabPageExtensions
{
        private struct TabPageData
        {
            internal int Index;
            internal TabControl Parent;
            internal TabPage Page;

            internal TabPageData(int index, TabControl parent, TabPage page)
            {
                Index = index;
                Parent = parent;
                Page = page;
            }

            internal static string GetKey(TabControl tabCtrl, TabPage tabPage)
            {
                string key = "";
                if (tabCtrl != null && tabPage != null)
                {
                    key = String.Format("{0}:{1}", tabCtrl.Name, tabPage.Name);
                }
                return key;
            }
        }

        private static Dictionary<string, TabPageData> hiddenPages = new Dictionary<string, TabPageData>();

        public static void SetVisible(this TabPage page, TabControl parent)
        {
            if (parent != null && !parent.IsDisposed)
            {
                TabPageData tpinfo;

                string key = TabPageData.GetKey(parent, page);
                if (hiddenPages.ContainsKey(key))
                {
                    tpinfo = hiddenPages[key];
                    if (tpinfo.Index < parent.TabPages.Count)
                        parent.TabPages.Insert(tpinfo.Index, tpinfo.Page); // add the page in the same position it had
                    else
                        parent.TabPages.Add(tpinfo.Page);
                    hiddenPages.Remove(key);
                }
            }
        }

        public static void SetInvisible(this TabPage page)
        {
            if (IsVisible(page))
            {
                TabControl tabCtrl = (TabControl)page.Parent;
                TabPageData tpinfo;
                tpinfo = new TabPageData(tabCtrl.TabPages.IndexOf(page), tabCtrl, page);
                tabCtrl.TabPages.Remove(page);
                hiddenPages.Add(TabPageData.GetKey(tabCtrl, page), tpinfo);
            }
        }

        public static bool IsVisible(this TabPage page)
        {
            return page != null && page.Parent != null; // when Parent is null the tab page does not belong to any container
        }

        public static void CleanUpHiddenPages(this TabPage page)
        {
            foreach (TabPageData info in hiddenPages.Values)
            {
                if (info.Parent != null && info.Parent.Equals((TabControl)page.Parent))
                    info.Page.Dispose();
            }
        }

    }
于 2011-12-15T17:21:19.413 回答
4

我更喜欢使平面样式外观: https ://stackoverflow.com/a/25192153/5660876

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

但是每个 tabPage 都会显示一个像素,因此如果您删除每个 tabpage 的所有文本,那么这些选项卡在运行时将完全不可见。

    foreach (TabPage tab in tabControl1.TabPages)
    {
        tab.Text = "";
    }

之后,我使用树视图来更改标签页...单击节点。

于 2016-04-08T22:24:50.273 回答
3

另一种方法是使用两个选项卡控件,一个可见,一个不可见。您可以像这样(vb.net)将选项卡从一个移动到另一个:

If Me.chkShowTab1.Checked = True Then
    Me.tabsShown.TabPages.Add(Me.tabsHidden.TabPages("Tab1"))
    Me.tabsHidden.TabPages.RemoveByKey("Tab1")
Else
    Me.tabsHidden.TabPages.Add(Me.tabsShown.TabPages("Tab1"))
    Me.tabsShown.TabPages.RemoveByKey("Tab1")
End If

如果 tab 顺序很重要,请将 tabsShown 上的 .Add 方法更改为 .Insert 并指定序号位置。一种方法是调用返回所需序数位置的例程。

于 2012-10-27T02:52:01.093 回答
2

您可以随时隐藏或显示标签页。

'in VB
myTabControl.TabPages(9).Hide() 'to hide the tabpage that has index 9
myTabControl.TabPages(9).Show() 'to show the tabpage that has index 9
于 2013-09-12T14:16:56.080 回答
1

我有我的示例代码工作,但想让它更好地引用列表中的选项卡:

Public Class Form1
    Dim State1 As Integer = 1
    Dim AllTabs As List(Of TabPage) = New List(Of TabPage)

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        Check1(State1)
        State1 = CInt(IIf(State1 = 1, 0, 1))
    End Sub

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        AllTabs.Add(TabControl1.TabPages("TabPage1"))
        AllTabs.Add(TabControl1.TabPages("TabPage2"))
    End Sub

    Sub Check1(ByVal No As Integer)
        If TabControl1.TabPages.ContainsKey("TabPage1") Then
            TabControl1.TabPages.Remove(TabControl1.TabPages("TabPage1"))
        End If
        If TabControl1.TabPages.ContainsKey("TabPage2") Then
            TabControl1.TabPages.Remove(TabControl1.TabPages("TabPage2"))
        End If
        TabControl1.TabPages.Add(AllTabs(No))
    End Sub
End Class
于 2010-07-29T18:06:34.703 回答
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);
                }
            }
        };
    }

像这样使用:

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

通过保留对匿名函数实例的引用来保留原始排序。

于 2012-11-14T04:49:30.203 回答
1

It looks easier for me to clear all TabPages add add those wished:

PropertyTabControl.TabPages.Clear();
        PropertyTabControl.TabPages.Add(AspectTabPage);
        PropertyTabControl.TabPages.Add(WerkstattTabPage);

or

PropertyTabControl.TabPages.Clear();
        PropertyTabControl.TabPages.Add(TerminTabPage);
于 2014-01-14T16:06:37.503 回答
1

有人将 C# 答案合并到这个答案中,所以我必须在这里发布我的答案。我不喜欢其他解决方案,所以我创建了一个帮助类,它可以更轻松地隐藏/显示您的选项卡,同时保留选项卡的顺序。

/// <summary>
/// Memorizes the order of tabs upon creation to make hiding / showing tabs more
/// straightforward. Instead of interacting with the TabCollection, use this class
/// instead.
/// </summary>
public class TabPageHelper
{
    private List<TabPage> _allTabs;
    private TabControl.TabPageCollection _tabCollection;
    public Dictionary<string, int> TabOrder { get; private set; }

    public TabPageHelper( TabControl.TabPageCollection tabCollection )
    {
        _allTabs = new List<TabPage>();
        TabOrder = new Dictionary<string, int>();
        foreach ( TabPage tab in tabCollection )
        {
            _allTabs.Add( tab );
        }
        _tabCollection = tabCollection;
        foreach ( int index in Enumerable.Range( 0, tabCollection.Count ) )
        {
            var tab = tabCollection[index];
            TabOrder[tab.Name] = index;
        }
    }

    public void ShowTabPage( string tabText )
    {
        TabPage page = _allTabs
            .Where( t => string.Equals( t.Text, tabText, StringComparison.CurrentCultureIgnoreCase ) )
            .First();
        int tabPageOrder = TabOrder[page.Name];
        if ( !_tabCollection.Contains( page ) )
        {
            _tabCollection.Insert( tabPageOrder, page );
        }
    }

    public void HideTabPage( string tabText )
    {
        TabPage page = _allTabs
            .Where( t => string.Equals( t.Text, tabText, StringComparison.CurrentCultureIgnoreCase ) )
            .First();
        int tabPageOrder = TabOrder[page.Name];
        if ( _tabCollection.Contains( page ) )
        {
            _tabCollection.Remove( page );
        }
    }
}

要使用该类,请在通过传入选项卡控件的 TabPages 属性初始化组件后,在表单加载方法中实例化它。

public Form1()
{
    InitializeComponent();
    _tabHelper = new TabPageHelper( tabControl1.TabPages );
}

您的所有标签页都应该存在于应用程序加载中(即:在设计视图中),因为该类会在隐藏/显示时记住标签页的顺序。您可以在整个应用程序中选择性地隐藏或显示它们,如下所示:

_tabHelper.HideTabPage("Settings");
_tabHelper.ShowTabPage("Schedule");
于 2019-06-27T18:44:05.783 回答
0

至少有两种方法可以在软件中编写解决方案...感谢您发布答案。只是想用另一个版本更新它。TabPage 数组用于隐藏选项卡控件。在 Load 事件期间,TabControl 中的 TabPages 被复制到影子数组中。稍后,此影子数组用作将 TabPages 复制到 TabControl 中的源……并以所需的呈现顺序。

    Private tabControl1tabPageShadow() As TabPage = Nothing

    Private Sub Form2_DailyReportPackageViewer_Load(sender As Object, e As EventArgs) Handles Me.Load
        LoadTabPageShadow()
    End Sub


    Private Sub LoadTabPageShadow()
        ReDim tabControl1tabPageShadow(TabControl1.TabPages.Count - 1)
        For Each tabPage In TabControl1.TabPages
            tabControl1tabPageShadow(tabPage.TabIndex) = tabPage
        Next
    End Sub

    Private Sub ViewAllReports(sender As Object, e As EventArgs) Handles Button8.Click
        TabControl1.TabPages.Clear()
        For Each tabPage In tabControl1tabPageShadow
            TabControl1.TabPages.Add(tabPage)
        Next
    End Sub


    Private Sub ViewOperationsReports(sender As Object, e As EventArgs) Handles Button10.Click
        TabControl1.TabPages.Clear()

        For tabCount As Integer = 0 To 9
            For Each tabPage In tabControl1tabPageShadow
                Select Case tabPage.Text
                    Case "Overview"
                        If tabCount = 0 Then TabControl1.TabPages.Add(tabPage)
                    Case "Production Days Under 110%"
                        If tabCount = 1 Then TabControl1.TabPages.Add(tabPage)
                    Case "Screening Status"
                        If tabCount = 2 Then TabControl1.TabPages.Add(tabPage)
                    Case "Rework Status"
                        If tabCount = 3 Then TabControl1.TabPages.Add(tabPage)
                    Case "Secondary by Machine"
                        If tabCount = 4 Then TabControl1.TabPages.Add(tabPage)
                    Case "Secondary Set Ups"
                        If tabCount = 5 Then TabControl1.TabPages.Add(tabPage)
                    Case "Secondary Run Times"
                        If tabCount = 6 Then TabControl1.TabPages.Add(tabPage)
                    Case "Primary Set Ups"
                        If tabCount = 7 Then TabControl1.TabPages.Add(tabPage)
                    Case "Variance"
                        If tabCount = 8 Then TabControl1.TabPages.Add(tabPage)
                    Case "Schedule Changes"
                        If tabCount = 9 Then TabControl1.TabPages.Add(tabPage)
                End Select
            Next
        Next


于 2020-08-21T14:06:31.163 回答
0
    Public Shared HiddenTabs As New List(Of TabPage)()
Public Shared Visibletabs As New List(Of TabPage)()
Public Shared Function ShowTab(tab_ As TabPage, show_tab As Boolean)
    Select Case show_tab
        Case True
            If Visibletabs.Contains(tab_) = False Then Visibletabs.Add(tab_)
            If HiddenTabs.Contains(tab_) = True Then HiddenTabs.Remove(tab_)
        Case False
            If HiddenTabs.Contains(tab_) = False Then HiddenTabs.Add(tab_)
            If Visibletabs.Contains(tab_) = True Then Visibletabs.Remove(tab_)
    End Select
    For Each r In HiddenTabs
        Try
            Dim TC As TabControl = r.Parent
            If TC.Contains(r) = True Then TC.TabPages.Remove(r)
        Catch ex As Exception

        End Try
    Next
    For Each a In Visibletabs
        Try
            Dim TC As TabControl = a.Parent
            If TC.Contains(a) = False Then TC.TabPages.Add(a)
        Catch ex As Exception

        End Try
    Next
End Function
于 2017-03-17T14:57:02.607 回答
0

我一直在使用相同的方法将隐藏的 TabPages 保存在私人列表中,但问题是当我想再次显示 TabPage 时,它​​们不会出现在原始位置(顺序)。所以,最后,我在 VB 中编写了一个类,用两种方法添加 TabControl:HideTabPageByName 和 ShowTabPageByName。您可以只调用传递名称的方法(而不是 TabPage 实例)。

Public Class CS_Control_TabControl
    Inherits System.Windows.Forms.TabControl

    Private mTabPagesHidden As New Dictionary(Of String, System.Windows.Forms.TabPage)
    Private mTabPagesOrder As List(Of String)

    Public Sub HideTabPageByName(ByVal TabPageName As String)
        If mTabPagesOrder Is Nothing Then
            ' The first time the Hide method is called, save the original order of the TabPages
            mTabPagesOrder = New List(Of String)
            For Each TabPageCurrent As TabPage In Me.TabPages
                mTabPagesOrder.Add(TabPageCurrent.Name)
            Next
        End If

        If Me.TabPages.ContainsKey(TabPageName) Then
            Dim TabPageToHide As TabPage

            ' Get the TabPage object
            TabPageToHide = TabPages(TabPageName)
            ' Add the TabPage to the internal List
            mTabPagesHidden.Add(TabPageName, TabPageToHide)
            ' Remove the TabPage from the TabPages collection of the TabControl
            Me.TabPages.Remove(TabPageToHide)
        End If
    End Sub

    Public Sub ShowTabPageByName(ByVal TabPageName As String)
        If mTabPagesHidden.ContainsKey(TabPageName) Then
            Dim TabPageToShow As TabPage

            ' Get the TabPage object
            TabPageToShow = mTabPagesHidden(TabPageName)
            ' Add the TabPage to the TabPages collection of the TabControl
            Me.TabPages.Insert(GetTabPageInsertionPoint(TabPageName), TabPageToShow)
            ' Remove the TabPage from the internal List
            mTabPagesHidden.Remove(TabPageName)
        End If
    End Sub

    Private Function GetTabPageInsertionPoint(ByVal TabPageName As String) As Integer
        Dim TabPageIndex As Integer
        Dim TabPageCurrent As TabPage
        Dim TabNameIndex As Integer
        Dim TabNameCurrent As String

        For TabPageIndex = 0 To Me.TabPages.Count - 1
            TabPageCurrent = Me.TabPages(TabPageIndex)
            For TabNameIndex = TabPageIndex To mTabPagesOrder.Count - 1
                TabNameCurrent = mTabPagesOrder(TabNameIndex)
                If TabNameCurrent = TabPageCurrent.Name Then
                    Exit For
                End If
                If TabNameCurrent = TabPageName Then
                    Return TabPageIndex
                End If
            Next
        Next
        Return TabPageIndex
    End Function

    Protected Overrides Sub Finalize()
        mTabPagesHidden = Nothing
        mTabPagesOrder = Nothing
        MyBase.Finalize()
    End Sub
End Class
于 2015-07-27T04:14:01.300 回答
0

添加和删​​除选项卡可能不太有效可能会有所帮助

隐藏/显示标签页 => 让 tabControl1 的 tabPage1

tapPage1.Parent = null;            //to hide tabPage1 from tabControl1
tabPage1.Parent = tabControl1;     //to show the tabPage1 in tabControl1
于 2019-05-03T10:53:51.750 回答
0

如果你负担得起使用 的Tag元素TabPage,你可以使用这个扩展方法

    public static void HideByRemoval(this TabPage tp)
    {
        TabControl tc = tp.Parent as TabControl;

        if (tc != null && tc.TabPages.Contains(tp))
        {
            // Store TabControl and Index
            tp.Tag = new Tuple<TabControl, Int32>(tc, tc.TabPages.IndexOf(tp));
            tc.TabPages.Remove(tp);
        }
    }

    public static void ShowByInsertion(this TabPage tp)
    {
        Tuple<TabControl, Int32> tagObj = tp.Tag as Tuple<TabControl, Int32>;

        if (tagObj?.Item1 != null)
        {
            // Restore TabControl and Index
            tagObj.Item1.TabPages.Insert(tagObj.Item2, tp);
        }
    }
于 2017-10-25T14:49:33.663 回答
0

在 Emile(和 Slugster)的回答的基础上,我发现扩展 TabControl(而不是 TabPages)更容易一些。通过这种方式,我可以通过一次调用将页面设置为不可见或可见,并且不必担心不可见页面的空父引用。

示例调用:MyTabControl.SetTabVisibilityExt("tabTests", isDeveloper);

public static class WinFormExtensions
{
    public static TabPage FindTabByNameExt( this TabControl tc, string tabName)
    {
        foreach (TabPage tab in tc.TabPages)
            if (tab.Name == tabName)
                return tab;

        return null;
    }

    private struct TabPageData
    {
        internal int Index;
        internal TabControl Parent;
        internal TabPage Page;

        internal TabPageData(int index, TabControl parent, TabPage page)
        {
            Index = index;
            Parent = parent;
            Page = page;
        }

        internal static string GetKey(TabControl tc, TabPage tabPage)
        {
            string key = "";
            if (tc == null || tabPage == null)
                return key;

            key = $"{tc.Name}:{tabPage.Name}";
            return key;
        }
        internal static string GetKey(TabControl tc, string tabName)
        {
            string key = "";
            if (tc == null)
                return key;

            key = $"{tc.Name}:{tabName}";
            return key;
        }
    }

    private static Dictionary<string, TabPageData> hiddenPages = new Dictionary<string, TabPageData>();

    public static void SetTabVisibleExt(this TabControl tc, string tabName)
    {
        if (tc == null || tc.IsDisposed)
            return;

        if (tc.IsTabVisibleExt(tabName))
            return;

        string key = TabPageData.GetKey(tc, tabName);
        if (hiddenPages.ContainsKey(key))
        {
            TabPageData tpinfo = hiddenPages[key];
            if (tpinfo.Index < tc.TabPages.Count)
                tc.TabPages.Insert(tpinfo.Index, tpinfo.Page); // add the page in the same position it had
            else
                tc.TabPages.Add(tpinfo.Page);

            hiddenPages.Remove(key);
            return;
        }
        else
            throw new ApplicationException($"TabControl={tc.Name} does not have Invisible TabPage={tabName}");
    }

    public static void SetTabInvisibleExt(this TabControl tc, string tabName)
    {
        if (tc == null || tc.IsDisposed)
            return;

        if (IsTabInvisibleExt(tc, tabName))
            return;

        TabPage page = tc.FindTabByNameExt(tabName);
        if (page != null)
        {
            string key = TabPageData.GetKey(tc, page);
            TabPageData tpInfo = new TabPageData(tc.TabPages.IndexOf(page), tc, page);
            tc.TabPages.Remove(page);
            hiddenPages.Add(key, tpInfo);
            return;
        }
        else // Could not find the tab, and it isn't already invisible.
            throw new ApplicationException($"TabControl={tc.Name} could not locate TabPage={tabName}");
    }

    // A convenience method to combine the SetTabInvisible and SetTabInvisible.
    public static void SetTabVisibilityExt(this TabControl tc, string tabName, bool? isVisible)
    {
        if (isVisible == null)
            return;

        if (isVisible.Value)
            tc.SetTabVisibleExt(tabName);
        else
            tc.SetTabInvisibleExt(tabName);
    }

    public static bool IsTabVisibleExt(this TabControl tc, string tabName)
    {
        TabPage page = tc.FindTabByNameExt(tabName);
        return page != null;
    }

    public static bool IsTabInvisibleExt(this TabControl tc, string tabName)
    {
        string key = TabPageData.GetKey(tc, tabName);
        return hiddenPages.ContainsKey(key);
    }

    public static void CleanUpHiddenPagesExt(this TabControl tc)
    {
        foreach (TabPageData info in hiddenPages.Values)
        {
            if (info.Parent != null && info.Parent.Equals((TabControl)tc))
                info.Page.Dispose();
        }
    }

}
于 2017-08-31T14:13:58.807 回答
-1

Always 代码应该简单且易于执行任务,以实现快速性能和良好的可靠性。

要将页面添加到 TabControl,以下代码就足够了。

If Tabcontrol1.Controls.Contains(TabPage1) Then
else Tabcontrol1.Controls.Add(TabPage1) End If

要从 TabControl 中删除页面,以下代码就足够了。

If Tabcontrol1.Controls.Contains(TabPage1) Then Tabcontrol1.Controls.Remove(TabPage1) End If

感谢 Stackoverflow.com 对程序员的真诚帮助。

于 2014-12-02T15:56:41.417 回答
-1

首先将选项卡复制到变量中,然后使用 insert 将其恢复。

TabPage tpresult = tabControl1.TabPages[0];
tabControl1.TabPages.RemoveAt(0);
tabControl1.TabPages.Insert(0, tpresult);
于 2021-10-21T12:58:41.920 回答
-1
TabPanel1.Visible = true; // Show Tabpage 1
TabPanel1.Visible = false; //Hide Tabpage 1
于 2017-07-12T09:27:43.300 回答
-3

您可以使用以下

tabcontainer.tabs(1).visible=true

1 是标签索引

于 2013-09-04T06:46:21.800 回答