2010-07-29 19 views
23

Próbuję pokazać lub ukryć zakładki zgodnie z wyborem użytkownika. Jeśli użytkownik wybierze płeć męska następnie tworzą dla samców w tabpage „męski” powinny być wyświetlane i jeżeli użytkownik wybierze żeński następnie podobną następny formularz powinien być wyświetlany w następnej zakładce „samicy”Ukrywanie i wyświetlanie stron kart w tabControl

Próbowałem za pomocą

tabControl1.TabPages.Remove(...) 

i

tabControl1.TabPages.Add(...) 

dodaje i usuwa tabpages ale robi tak straci na tabpages też moje kontrole ... nie widzę je z powrotem. jaki jest problem?

+1

jest własność Visible nie działa na stronach karty? – sukru

+3

Zweryfikowano: właściwość widoczna nie jest faktycznie widoczna na stronach kart. –

+1

A także metody Pokaż i Ukryj ... –

Odpowiedz

21

Możesz usunąć stronę karty z kolekcji TabControl.TabPages i zapisać ją na liście. Na przykład:

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); 
    } 
+0

Mam trudności ze znalezieniem strony zakładki ... mogę opublikować pełne np. zrozumiałem twoją metodę, ale zastanawiam się, jak odświeżyć kartę podczas dodawania, ponieważ została ona wcześniej usunięta. – KoolKabin

+0

Po prostu dodaj członka do swojej klasy. Projektant formularzy Windows już to robi, np. "TabPage1". –

+0

Piszę, aby odnieść się do strony tabPage1. Czy muszę napisać do mnie. TabPages ("tabPage1") lub co? – KoolKabin

1

mam przykładowy kod roboczy, ale chcemy, aby było nieco lepiej refrencing zakładkę z listy:

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

Poprawa na dobre rozwiązanie Hans Passant postanowiłem napisać Metoda rozszerzenia oparta na jego rozwiązaniu i dodawaniu innych rzeczy. Jestem zaskoczony, że nawet w .NET 4 ta podstawowa funkcjonalność nie została naprawiona.

  • zaimplementowano jako metodę rozszerzenia, które mogą być ponownie wykorzystane w bardziej przejrzysty sposób
  • Czyste sposób oczyszcza się tylko do strony sterowania jest umieszczona/czyszczone.
  • Gdy tylko jest to możliwe strona karty zostaje przywrócona do tej samej pozycji. Nie zawsze jest to możliwe, jeśli ukryjesz/wyświetlisz kilka stron kart.
  • Wykonuje kilka błędów i sprawdzanie parametrów.
  • Aby uczynić go niewidocznym, dowiaduje się o nim. Podczas renderowania musi być podana , ponieważ właściwość Parent ma wartość null, gdy strona z zakładkami została usunięta.


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

    } 
+0

Działa na poczęstunek - bardzo dziękuję. Możesz chcieć złożyć raport o błędzie, odkąd Stackoverflow zawiązuje początek i koniec twojego kodu. –

+0

Och, w jaki sposób mogę również ukryć strzałki dla użytkownika, gdy jest za dużo zakładek? –

29

Myślę, że odpowiedź jest znacznie łatwiejsze.

Aby ukryć kartę, możesz po prostu użyć metody, którą już wypróbowałeś lub sam wpisałeś na samej stronie TabPage.

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

a.s.o.

Usunięcie TabPage nie niszczy go i elementów sterujących na nim. Aby ponownie wskazują odpowiednią kartę wystarczy użyć następującego kodu

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

Inne podejście byłoby mieć dwa regulatory zakładki, po jednym widoczne i nie. Można przenieść zakładki z jednego do drugiego, tak (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 

Jeśli zamówienie karta jest ważna, zmienić metodę .Add na tabsShown do .Zastosowaæ i określić położenie porządkowej.Jednym ze sposobów na to jest wywołanie procedury, która zwraca pożądaną pozycję porządkową.

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

Używane tak:

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

Original zamawiania jest zatrzymywana przez zatrzymanie odwołanie do anonimowej przykład funkcji.

-2

można użyć Po

tabcontainer.tabs(1).visible=true 

1 jest tabindex

0

zawsze można ukryć lub pokazać tabpage.

'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 
+0

To nie działa dla mnie w Visual Studio 2008 – syam

1

Wygląda mi łatwiej wyczyścić wszystkie TabPages dodać dodać te życzył:

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

lub

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

Zawsze kody powinny być proste i łatwe do wykonania zadania dla wysokiej wydajności i dla dobrej niezawodności.

Aby dodać stronę do TabControl, wystarczy poniższy kod.

Jeśli Tabcontrol1.Controls.Contains (TabPage1) Następnie
inny Tabcontrol1.Controls.Add (TabPage1) End If

Aby usunąć stronę z TabControl poniższy kod wystarczy.

Jeśli Tabcontrol1.Controls.Contains (TabPage1) Następnie Tabcontrol1.Controls.Remove (TabPage1) End If

pragnę podziękować za dostarczenie stackoverflow.com szczerą pomoc dla programistów.

0

Używam tej samej metody zapisywania ukrytych stron TabPages na liście prywatnej, ale problem polega na tym, że gdy chcę ponownie wyświetlić TabPage, nie pojawiają się one w pierwotnej pozycji (kolejność). W końcu napisałem klasę w VB, aby dodać TabControl za pomocą dwóch metod: HideTabPageByName i ShowTabPageByName. Możesz po prostu wywołać metody przekazujące nazwę (a nie instancję 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 
0

Wolę zrobić płaski wygląd styl: https://stackoverflow.com/a/25192153/5660876

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

Ale jest piksel, który jest pokazany na każdym tabpage, więc jeśli usunąć cały tekst każdego tabpage, wówczas zakładki stają się doskonale niewidoczne w czasie działania.

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

Potem używam widoku drzewa, aby przejść przez zakładki ... klikając węzły.

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 
+0

Powinieneś dodać kilka komentarzy, szczegółowo, co dzieje się w podanym kodzie. – Mike

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

Witamy w Stack Overflow! Chociaż ten fragment kodu może rozwiązać pytanie, [w tym wyjaśnienie] (// meta.stackexchange.com/questions/114762/explaining-entirely-code-ans -answers) naprawdę pomaga poprawić jakość twojego posta. Pamiętaj, że odpowiadasz na pytanie przeznaczone dla czytelników w przyszłości, a te osoby mogą nie znać powodów sugestii dotyczących kodu. Proszę również starać się nie tłumić kodu za pomocą komentarzy wyjaśniających, co zmniejsza czytelność zarówno kodu, jak i objaśnień! – kayess

+0

To nie działa, przy okazji. Właściwość 'Visible' nic nie robi. – Nyerguds

0

A budynek na odpowiedź Emile (i Slugster), znalazłem to nieco łatwiej rozszerzyć TabControl (zamiast TabPages). W ten sposób mogę ustawić strony niewidoczne lub widoczne za pomocą jednego połączenia, a także nie muszę martwić się o zerowe odwołania do rodzica dla niewidocznych stron.

Przykład połączenia: 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(); 
     } 
    } 

} 
0

Jeśli możesz sobie pozwolić, aby użyć elementu Tag z TabPage, można użyć tej metody rozszerzenie

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); 
     } 
    } 
Powiązane problemy