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を削除しても、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でも、この基本的な機能が修正されていないことに驚いています。

  • より透過的に再利用できる拡張メソッドとして実装
  • クリーンアップ方法は、破棄/クリーンアップされているコントロールのページのみをクリーンアップします。
  • 可能な限り、タブページは同じ位置に復元されます。複数のタブページを表示/非表示にする場合、これが常に可能であるとは限りません。
  • エラーとパラメータのチェックを行います
  • それを見えなくするために、それはその親を見つけます。タブページが削除されたときに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();
            }
        }

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

別のアプローチは、2つのタブコントロールを使用することです。1つは表示され、もう1つは表示されません。次のようにタブを一方から他方に移動できます(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

タブの順序が重要な場合は、tabsShownの.Addメソッドを.Insertに変更し、序数の位置を指定します。これを行う1つの方法は、目的の序数位置を返すルーチンを呼び出すことです。

于 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

すべてのTabPageをクリアして、必要なものを追加する方が簡単に見えます。

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

また

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をプライベートリストに保存するのと同じアプローチを使用していますが、問題は、TabPageを再度表示したいときに、元の位置(順序)に表示されないことです。そこで、最後に、HideTabPageByNameとShowTabPageByNameの2つのメソッドを使用してTabControlを追加するクラスをVBで作成しました。(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
    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

そして、Emile(およびSlugster)の回答に基づいて、(TabPagesの代わりに)TabControlを拡張する方が少し簡単であることがわかりました。このようにして、1回の呼び出しでページを非表示または表示に設定できます。また、非表示のページのnullの親参照について心配する必要もありません。

呼び出し例: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 に答える
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

タブの追加と削除は少し効果が低いかもしれませんこれは役立つかもしれません

タブページを表示/非表示にするには=>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

ソフトウェアでソリューションをコーディングするには、少なくとも2つの方法があります...回答を投稿していただきありがとうございます。これを別のバージョンで更新したかっただけです。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 に答える
-1

パフォーマンスを高速化し、信頼性を高めるために、コードは常にシンプルで実行しやすいタスクである必要があります。

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
TabPanel1.Visible = true; // Show Tabpage 1
TabPanel1.Visible = false; //Hide Tabpage 1
于 2017-07-12T09:27:43.300 に答える
-1

最初にタブを変数にコピーし、次に挿入を使用してタブを元に戻します。

TabPage tpresult = tabControl1.TabPages[0];
tabControl1.TabPages.RemoveAt(0);
tabControl1.TabPages.Insert(0, tpresult);
于 2021-10-21T12:58:41.920 に答える
-3

あなたは以下を使うことができます

tabcontainer.tabs(1).visible=true

1はtabindexです

于 2013-09-04T06:46:21.800 に答える