在tabControl中隐藏和显示TabPages

时间:2010-07-29 16:50:04

标签: vb.net tabcontrol tabpage

我正在尝试根据用户选择显示或隐藏tabpages。如果用户选择性别男性,则应在标签页中显示男性形式“男性”,如果用户选择女性,则下一个标签中应显示相似的下一个表格“女性”

我尝试使用

tabControl1.TabPages.Remove(...)

tabControl1.TabPages.Add(...)

它添加并删除了tabpages,但这样做也会松开我在tabpages上的控件......我无法看到它们。这有什么问题?

18 个答案:

答案 0 :(得分:32)

我认为答案要容易得多。

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

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

a.s.o。

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

TabControl1.TabPages.Insert(0, TabPage1) 'Show male
TabControl1.TabPages.Insert(1, TabPage2) 'Show female

答案 1 :(得分:32)

您可以从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);
    }

答案 2 :(得分:6)

改善Hans Passant的优秀解决方案我决定根据他的解决方案编写扩展方法并添加其他内容。我很惊讶即使在.NET 4中这个基本功能还没有修复。

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


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

    }

答案 3 :(得分:2)

另一种方法是使用两个选项卡控件,一个是可见的,一个不是。您可以将标签从一个移动到另一个(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并指定序号位置。一种方法是调用返回所需序数位置的例程。

答案 4 :(得分: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

答案 5 :(得分: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");

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

答案 6 :(得分:1)

我看起来更容易清除所有愿望添加的TabPages:

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

PropertyTabControl.TabPages.Clear();
        PropertyTabControl.TabPages.Add(TerminTabPage);

答案 7 :(得分:0)

至少有两种方法可以用软件编写解决方案的代码...感谢您发布答案。只是想用另一个版本进行更新。 TabPage数组用于遮盖Tab控件。在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


答案 8 :(得分:0)

有人将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");

答案 9 :(得分:0)

添加和删除选项卡的效果可能会稍差 可能会有帮助

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

tapPage1.Parent = null;            //to hide tabPage1 from tabControl1
tabPage1.Parent = tabControl1;     //to show the tabPage1 in tabControl1

答案 10 :(得分:0)

如果您能够使用Tag的{​​{1}}元素,则可以使用此扩展方法

TabPage

答案 11 :(得分:0)

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

示例电话:   MyTabControl.SetTabVisibilityExt(&#34; tabTests&#34;,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();
        }
    }

}

答案 12 :(得分: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

答案 13 :(得分: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

答案 14 :(得分:0)

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

'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

答案 15 :(得分:-1)

TabPanel1.Visible = true; // Show Tabpage 1
TabPanel1.Visible = false; //Hide Tabpage 1

答案 16 :(得分:-1)

始终代码应该简单易行,以实现快速性能和良好的可靠性。

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

如果Tabcontrol1.Controls.Contains(TabPage1)那么
其他 Tabcontrol1.Controls.Add(TabPage1) 结束如果

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

如果Tabcontrol1.Controls.Contains(TabPage1)那么 Tabcontrol1.Controls.Remove(TabPage1) 结束如果

我要感谢Stackoverflow.com为程序员提供真诚的帮助。

答案 17 :(得分:-2)

您可以使用以下

tabcontainer.tabs(1).visible=true

1是tabindex