vb.net 在 tabControl 中隐藏和显示 TabPages
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3365025/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hiding and Showing TabPages in tabControl
提问by KoolKabin
I am trying to show or hide tabpages as per user choice. If user selects gender male then form for male in a tabpage "male" should be displayed and if user selects female then similar next form should be displayed in next tab "female"
我正在尝试根据用户选择显示或隐藏标签页。如果用户选择性别男性,则应在标签页“男性”中显示男性表单,如果用户选择女性,则应在下一个选项卡“女性”中显示类似的下一个表单
I tried using
我尝试使用
tabControl1.TabPages.Remove(...)
and
和
tabControl1.TabPages.Add(...)
It adds and removes the tabpages but doing so will loose my controls on tabpages too... i can't see them back. what's the problem here?
它添加和删除标签页,但这样做也会失去我对标签页的控制......我看不到它们。这里有什么问题?
采纳答案by Hans Passant
You could remove the tab page from the TabControl.TabPages collection and store it in a list. For example:
您可以从 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);
}
回答by Mike
I think the answer is much easier.
我认为答案要容易得多。
To hide the tab you just can use the way you already tried or adressing the TabPage itself.
要隐藏选项卡,您可以使用您已经尝试过的方式或对 TabPage 本身进行寻址。
TabControl1.TabPages.Remove(TabPage1) 'Could be male
TabControl1.TabPages.Remove(TabPage2) 'Could be female
a.s.o.
阿苏
Removing the TabPage does not destroy it and the controls on it. To show the corresponding tab again just use the following code
删除 TabPage 不会破坏它及其上的控件。要再次显示相应的选项卡,只需使用以下代码
TabControl1.TabPages.Insert(0, TabPage1) 'Show male
TabControl1.TabPages.Insert(1, TabPage2) 'Show female
回答by Emile
Improving on the good solution by Hans Passant I decided to write an extension method based on his solution and adding other stuff as well. I am surprised that even in .NET 4 this basic functionality hasn't been fixed.
改进 Hans Passant 的好解决方案 我决定基于他的解决方案编写一个扩展方法并添加其他内容。我很惊讶,即使在 .NET 4 中,这个基本功能也没有得到修复。
- Implemented it as an Extension Method that can be reused in a more transparent manner
- The clean up method only cleans up the pages of the control being disposed/cleaned up.
- Whenever possible the tab page is restored to its same position. This isn't always possible if you hide/show several tab pages.
- It does some error and parameter checking
- To make it invisible it finds out its parent. When making visible it has to be given because the Parent property is null when the tab page has been removed.
- 将其实现为可以以更透明的方式重用的扩展方法
- 清理方法只清理正在处理/清理的控件的页面。
- 只要有可能,标签页就会恢复到原来的位置。如果您隐藏/显示多个标签页,这并不总是可行的。
- 它会做一些错误和参数检查
- 为了使它不可见,它会找到它的父级。当使其可见时,必须给出它,因为当标签页被移除时 Parent 属性为空。
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();
}
}
}
回答by Mmm
A different approach would be to have two tab controls, one visible, and one not. You can move the tabs from one to the other like this (vb.net):
一种不同的方法是有两个选项卡控件,一个可见,一个不可见。您可以像这样(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
If the tab order is important, change the .Add method on tabsShown to .Insert and specify the ordinal position. One way to do that is to call a routine that returns the desired ordinal position.
如果 Tab 键顺序很重要,请将 tabsShown 上的 .Add 方法更改为 .Insert 并指定序号位置。一种方法是调用返回所需顺序位置的例程。
回答by Rob
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);
}
}
};
}
Used like this:
像这样使用:
var showOnly = this.TabContainer1.GetTabHider();
showOnly((tab) => tab.Text != "tabPage1");
Original ordering is retained by retaining a reference to the anonymous function instance.
通过保留对匿名函数实例的引用来保留原始排序。
回答by KoolKabin
I have my sample code working but want to make it somewhat more better refrencing the tab from list:
我有我的示例代码工作,但想让它更好地引用列表中的选项卡:
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
回答by Paulo Lima
you can always hide or show the 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
回答by staecker
It looks easier for me to clear all TabPages add add those wished:
我看起来更容易清除所有 TabPages 添加添加那些希望的:
PropertyTabControl.TabPages.Clear();
PropertyTabControl.TabPages.Add(AspectTabPage);
PropertyTabControl.TabPages.Add(WerkstattTabPage);
or
或者
PropertyTabControl.TabPages.Clear();
PropertyTabControl.TabPages.Add(TerminTabPage);
回答by GeMe
I prefer to make the flat style appearance: https://stackoverflow.com/a/25192153/5660876
我更喜欢做扁平化的外观:https: //stackoverflow.com/a/25192153/5660876
tabControl1.Appearance = TabAppearance.FlatButtons;
tabControl1.ItemSize = new Size(0, 1);
tabControl1.SizeMode = TabSizeMode.Fixed;
But there is a pixel that is shown at every tabPage, so if you delete all the text of every tabpage, then the tabs become invisible perfectly at run-time.
但是每个 tabPage 都会显示一个像素,因此如果您删除每个 tabpage 的所有文本,那么这些 tab 在运行时就会完全不可见。
foreach (TabPage tab in tabControl1.TabPages)
{
tab.Text = "";
}
After that i use a treeview, to change through the tabpages... clicking on the nodes.
之后,我使用树视图来更改标签页...单击节点。
回答by Mattheu Norwood
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