Скрытие и отображение вкладок в tabControl

Я пытаюсь показать или скрыть вкладки в соответствии с выбором пользователя. Если пользователь выбирает гендерного мужчины, тогда форма для мужчины на вкладке "мужчина" должна отображаться, и если пользователь выбирает женщину, то аналогичная следующая форма должна отображаться на следующей вкладке "женщина"

Я попытался использовать

tabControl1.TabPages.Remove(...)

и

tabControl1.TabPages.Add(...)

Он добавляет и удаляет табуляции, но при этом также теряют мои элементы управления на вкладках... я не могу их увидеть. в чем проблема?

Ответ 1

Вы можете удалить вкладку из коллекции 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

Я думаю, что ответ намного проще.

Чтобы скрыть вкладку, вы можете просто использовать способ, которым вы уже пробовали, или адрес самой вкладки.

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

Ответ 3

Улучшение хорошего решения Hans Passant Я решил написать метод расширения, основанный на его решении, и добавить другие материалы. Я удивлен, что даже в .NET 4 эта базовая функциональность не была исправлена.

  • Реализован как метод расширения, который может быть повторно использован более прозрачным образом.
  • Метод очистки только очищает страницы управляющего устройства, расположенные/очищенные.
  • По возможности, страница вкладки восстанавливается в том же положении. Это не всегда возможно, если вы скрываете/показываете несколько страниц вкладок.
  • Выполняется некоторая проверка ошибок и параметров
  • Чтобы сделать его невидимым, он узнает своего родителя. При появлении видимых нужно дать потому что свойство "Родитель" равно 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();
            }
        }

    }

Ответ 4

Другой подход состоял бы в том, чтобы иметь два элемента управления вкладками, один видимый, а другой нет. Вы можете переместить вкладки от одного к другому, как это (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

Если порядок вкладок важен, измените метод .Add на вкладках Shown, чтобы .Insert и указать порядковое положение. Один из способов сделать это - вызвать процедуру, которая возвращает желаемую порядковую позицию.

Ответ 5

У меня есть мой пример кода, но хочу сделать его несколько лучше, переустанавливая вкладку из списка:

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

Ответ 6

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

Оригинальное упорядочение сохраняется, сохраняя ссылку на экземпляр анонимной функции.

Ответ 7

Мне легче прояснить все вкладки добавления добавить желаемое:

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

или

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

Ответ 8

Я предпочитаю сделать стиль в стиле: fooobar.com/questions/48163/...

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

Но есть пиксель, который отображается на каждой вкладке, поэтому, если вы удаляете весь текст каждой вкладки, то вкладки становятся невидимыми во время выполнения.

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

После этого я использую древовидное представление, чтобы изменить его по вкладкам... нажав на узлы.

Ответ 9

вы всегда можете скрыть или показать вкладку.

'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

Ответ 10

Я использовал тот же подход для сохранения скрытых вкладок в приватном списке, но проблема в том, что, когда я хочу снова показать 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

Ответ 11

    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

Ответ 12

И, основываясь на ответе Эмиля (и 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();
        }
    }

}

Ответ 13

Если вы можете позволить использовать элемент 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);
        }
    }

Ответ 14

Добавление и удаление вкладки может быть немного менее эффективным. Может быть, это поможет

Чтобы скрыть/показать вкладку => позвольте tabPage1 из tabControl1

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

Ответ 15

Кто-то слил ответ С# в этот, поэтому я должен опубликовать свой ответ здесь. Мне не понравились другие решения, поэтому я создал вспомогательный класс, который позволит легче скрывать/показывать ваши вкладки, сохраняя порядок вкладок.

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

Ответ 16

Всегда коды должны быть простыми и легкими для выполнения задач для быстрой работы и хорошей надежности.

Чтобы добавить страницу в TabControl, достаточно следующего кода.

Если Tabcontrol1.Controls.Contains(TabPage1) Затем
еще Tabcontrol1.Controls.Add(TabPage1) End If

Чтобы удалить страницу из TabControl, достаточно следующего кода.

Если Tabcontrol1.Controls.Contains(TabPage1) Затем Tabcontrol1.Controls.Remove(TabPage1) End If

Я хочу поблагодарить Stackoverflow.com за искреннюю помощь программистам.

Ответ 17

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

Ответ 18

Вы можете использовать следующие

tabcontainer.tabs(1).visible=true

1 - tabindex