我正在尝试根据用户选择显示或隐藏标签页。如果用户选择性别为男性,则应在标签页“男性”中显示男性表单,如果用户选择女性,则应在下一个选项卡“女性”中显示类似的下一个表单
我尝试使用
tabControl1.TabPages.Remove(...)
和
tabControl1.TabPages.Add(...)
它添加和删除标签页,但这样做也会失去我对标签页的控制......我看不到它们。这里有什么问题?
我正在尝试根据用户选择显示或隐藏标签页。如果用户选择性别为男性,则应在标签页“男性”中显示男性表单,如果用户选择女性,则应在下一个选项卡“女性”中显示类似的下一个表单
我尝试使用
tabControl1.TabPages.Remove(...)
和
tabControl1.TabPages.Add(...)
它添加和删除标签页,但这样做也会失去我对标签页的控制......我看不到它们。这里有什么问题?
我认为答案要容易得多。
要隐藏选项卡,您可以使用您已经尝试过的方式或处理 TabPage 本身。
TabControl1.TabPages.Remove(TabPage1) 'Could be male
TabControl1.TabPages.Remove(TabPage2) 'Could be female
阿苏
删除 TabPage 不会破坏它及其上的控件。要再次显示相应的选项卡,只需使用以下代码
TabControl1.TabPages.Insert(0, TabPage1) 'Show male
TabControl1.TabPages.Insert(1, TabPage2) 'Show female
您可以从 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);
}
改进 Hans Passant 的好解决方案我决定根据他的解决方案编写一个扩展方法,并添加其他东西。令我惊讶的是,即使在 .NET 4 中,这个基本功能也没有得到修复。
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();
}
}
}
我更喜欢使平面样式外观: 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 = "";
}
之后,我使用树视图来更改标签页...单击节点。
另一种方法是使用两个选项卡控件,一个可见,一个不可见。您可以像这样(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 并指定序号位置。一种方法是调用返回所需序数位置的例程。
您可以随时隐藏或显示标签页。
'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
我有我的示例代码工作,但想让它更好地引用列表中的选项卡:
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);
}
}
};
}
像这样使用:
var showOnly = this.TabContainer1.GetTabHider();
showOnly((tab) => tab.Text != "tabPage1");
通过保留对匿名函数实例的引用来保留原始排序。
It looks easier for me to clear all TabPages add add those wished:
PropertyTabControl.TabPages.Clear();
PropertyTabControl.TabPages.Add(AspectTabPage);
PropertyTabControl.TabPages.Add(WerkstattTabPage);
or
PropertyTabControl.TabPages.Clear();
PropertyTabControl.TabPages.Add(TerminTabPage);
有人将 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");
至少有两种方法可以在软件中编写解决方案...感谢您发布答案。只是想用另一个版本更新它。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
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
我一直在使用相同的方法将隐藏的 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
添加和删除选项卡可能不太有效可能会有所帮助
隐藏/显示标签页 => 让 tabControl1 的 tabPage1
tapPage1.Parent = null; //to hide tabPage1 from tabControl1
tabPage1.Parent = tabControl1; //to show the tabPage1 in tabControl1
如果你负担得起使用 的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);
}
}
在 Emile(和 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();
}
}
}
Always 代码应该简单且易于执行任务,以实现快速性能和良好的可靠性。
要将页面添加到 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 对程序员的真诚帮助。
首先将选项卡复制到变量中,然后使用 insert 将其恢复。
TabPage tpresult = tabControl1.TabPages[0];
tabControl1.TabPages.RemoveAt(0);
tabControl1.TabPages.Insert(0, tpresult);
TabPanel1.Visible = true; // Show Tabpage 1
TabPanel1.Visible = false; //Hide Tabpage 1
您可以使用以下
tabcontainer.tabs(1).visible=true
1 是标签索引