Cacher et afficher des onglets dans tabControl
j'essaie de montrer ou de cacher les onglets au choix de l'utilisateur. Si l'utilisateur sélectionne le sexe masculin alors de la forme masculine dans un élément tabpage "homme" doit être affiché et si l'utilisateur sélectionne femelles semblables formulaire suivant doit être affiché dans l'onglet suivant "femelle"
j'ai essayé d'utiliser
tabControl1.TabPages.Remove(...)
et
tabControl1.TabPages.Add(...)
Il ajoute et supprime les tabpages mais cela lâche mes contrôles sur tabpages... je ne peux pas les voir revenir. ce qui est le problème ici?
16 réponses
vous pouvez supprimer la page de TabControl.TabPages collection et stocker dans une liste. Par exemple:
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);
}
je pense que la réponse est beaucoup plus facile.
pour masquer l'onglet, vous pouvez juste utiliser la façon dont vous avez déjà essayé ou en adressant la page D'onglet elle-même.
TabControl1.TabPages.Remove(TabPage1) 'Could be male
TabControl1.TabPages.Remove(TabPage2) 'Could be female
A. S. O.
supprimer la page D'onglet ne le détruit pas et les contrôles sur elle. Pour afficher à nouveau l'onglet correspondant il suffit d'utiliser le code suivant
TabControl1.TabPages.Insert(0, TabPage1) 'Show male
TabControl1.TabPages.Insert(1, TabPage2) 'Show female
améliorer la bonne solution by Hans Passant j'ai décidé d'écrire une méthode d'extension basée sur sa solution et d'ajouter d'autres choses aussi. Je suis surpris que même dans .NET 4 cette fonctionnalité de base n'ait pas été corrigée.
- mise en œuvre en tant que méthode D'Extension pouvant être réutilisée de manière plus transparente
- la méthode de nettoyage ne nettoie que les pages du contrôle à éliminer/nettoyer.
- Dans la mesure du possible, la page de l'onglet est restaurée dans la même position. Ce n'est pas toujours possible si vous masquez / montrez plusieurs pages d'onglets.
- Il ne des erreurs et de vérification des paramètres
- pour le rendre invisible il découvre son parent. Lorsqu'il est rendu visible, il doit être donné parce que la propriété Parent est nulle lorsque la page de l'onglet a été retirée.
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();
}
}
}
une approche différente serait d'avoir deux commandes tab, l'une visible et l'autre Non. Vous pouvez déplacer les onglets de l'un à l'autre comme ceci (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
si l'ordre de l'onglet est important, changez le .Ajouter la méthode sur tabsShown to .Insérer et spécifier la position ordinale. Une façon de le faire est d'appeler une routine qui renvoie souhaité en position ordinale.
mon exemple de code fonctionne, mais je veux le rendre un peu plus conforme à l'onglet de la liste:
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
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);
}
}
};
}
utilisé comme ceci:
var showOnly = this.TabContainer1.GetTabHider();
showOnly((tab) => tab.Text != "tabPage1");
Origine de la commande est conservé par le maintien d'une référence à la fonction anonyme instance.
il semble plus facile pour moi de supprimer tous les onglets ajouter ajouter ceux qui souhaitent:
PropertyTabControl.TabPages.Clear();
PropertyTabControl.TabPages.Add(AspectTabPage);
PropertyTabControl.TabPages.Add(WerkstattTabPage);
ou
PropertyTabControl.TabPages.Clear();
PropertyTabControl.TabPages.Add(TerminTabPage);
je préfère faire l'apparence du style plat: https://stackoverflow.com/a/25192153/5660876
tabControl1.Appearance = TabAppearance.FlatButtons;
tabControl1.ItemSize = new Size(0, 1);
tabControl1.SizeMode = TabSizeMode.Fixed;
mais il y a un pixel qui s'affiche à chaque page d'onglet, donc si vous supprimez tout le texte de chaque page d'onglet, alors les onglets deviennent parfaitement invisibles à l'exécution.
foreach (TabPage tab in tabControl1.TabPages)
{
tab.Text = "";
}
après cela j'utilise un treeview, pour changer à travers les onglets... en cliquant sur les nœuds.
vous pouvez toujours cacher ou afficher l'onglet.
'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
j'ai utilisé la même approche pour sauvegarder les onglets cachés dans une liste privée, mais le problème est que quand je veux afficher à nouveau L'onglet, ils n'apparaissent pas dans la position originale (ordre). Donc, finalement, j'ai écrit une classe dans VB pour ajouter le TabControl avec deux méthodes: HideTabPageByName et ShowTabPageByName. Vous pouvez simplement appeler les méthodes passant le nom (pas L'instance de 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
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
TabPanel1.Visible = true; // Show Tabpage 1
TabPanel1.Visible = false; //Hide Tabpage 1
et en me basant sur la réponse D'Emile (et Slugster), j'ai trouvé un peu plus facile d'étendre le TabControl (au lieu des TabPages). De cette façon, je peux définir des pages invisibles ou visibles avec un seul appel, et aussi ne pas avoir à se soucier des références parents nulles pour les pages invisibles.
exemple d'appel: MyTabControl.Settabuvisibilityext ("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();
}
}
}
si vous pouvez vous permettre d'utiliser l'élément Tag
de la TabPage
, vous pouvez utiliser ces méthodes d'extension
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);
}
}
toujours les codes doivent être simples et faciles à exécuter des tâches pour des performances rapides et pour une bonne fiabilité.
pour ajouter une page à un TabControl, le code suivant est suffisant.
Si Tabcontrol1.Contrôle.Contient (TabPage1) Puis
autre
Contrôleonglet1.Contrôle.Ajouter (TabPage1)
Fin Si
pour supprimer une page D'un TabControl, le code suivant est suffisant.
Si Tabcontrol1.Contrôle.Contient Alors (TabPage1) Contrôleonglet1.Contrôle.Supprimer (TabPage1) Fin Si
je tiens à remercier Stackoverflow.com pour fournir une aide sincère aux programmeurs.
vous pouvez utiliser ce qui suit""
tabcontainer.tabs(1).visible=true
1 est tabindex