vb.net 在 VB .NET 中隐藏和显示 TabPages - TabManager
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18058034/
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 VB .NET - TabManager
提问by 4ntibala
I try to hide and show tabpages dynamically at runtime. For this I converted the code of Emile from hereto vb.net and the resulted problem is that tabpages cannot be shown anymore after they were hidden. At least not if they were set to invisible somewhere else than where I am trying set them visible.
我尝试在运行时动态隐藏和显示标签页。为此,我将 Emile 的代码从这里转换为 vb.net,结果问题是标签页在隐藏后无法再显示。至少如果它们被设置为不可见,而不是我试图将它们设置为可见的其他地方。
edit:
编辑:
After a long discussion i finally came up with a working result. i corrected the calling procedures and now this code works. It can hide and show tabpages that reside on any form, just like the original versiondoes. Thanks go to user varocarbas..
经过长时间的讨论,我终于想出了一个可行的结果。我更正了调用程序,现在此代码有效。它可以隐藏和显示驻留在任何表单上的标签页,就像原始版本一样。感谢用户 varocarbas ..
Hiding a tabpage:
隐藏标签页:
clsTabManager.SetInvisible(tabPage)
Showing a tabpage (call from anyclass/form):
显示标签页(从任何类/表单调用):
clsTabManager.SetVisible(FormWithTabControl.tabPage, FormWithTabControl.TabControl)
Showing a tabpage (call from Form where TabControl resides):
显示标签页(从 TabControl所在的Form 调用):
clsTabManager.SetVisible(tabPage, TabControl)
clsTabmanager:
clsTabmanager:
Public Class clsTabManager
Private Structure TabPageData
Friend Index As Integer
Friend Parent As TabControl
Friend Page As TabPage
Friend Sub New(index__1 As Integer, parent__2 As TabControl, page__3 As TabPage)
Index = index__1
Parent = parent__2
Page = page__3
End Sub
Friend Shared Function GetKey(tabCtrl As TabControl, tabPage As TabPage) As String
Dim key As String = ""
If tabCtrl IsNot Nothing AndAlso tabPage IsNot Nothing Then
key = [String].Format("{0}:{1}", tabCtrl.Name, tabPage.Name)
End If
Return key
End Function
End Structure
Private hiddenPages As New Dictionary(Of String, TabPageData)()
Public Sub SetVisible(page As TabPage, parent As TabControl)
If parent IsNot Nothing AndAlso Not parent.IsDisposed Then
Dim tpinfo As TabPageData
Dim key As String = TabPageData.GetKey(parent, page)
If hiddenPages.ContainsKey(key) Then
tpinfo = hiddenPages(key)
If tpinfo.Index < parent.TabPages.Count Then
parent.TabPages.Insert(tpinfo.Index, tpinfo.Page)
Else
' add the page in the same position it had
parent.TabPages.Add(tpinfo.Page)
End If
hiddenPages.Remove(key)
End If
End If
End Sub
Public Sub SetInvisible(page As TabPage)
If IsVisible(page) Then
Dim tabCtrl As TabControl = DirectCast(page.Parent, TabControl)
Dim tpinfo As TabPageData
tpinfo = New TabPageData(tabCtrl.TabPages.IndexOf(page), tabCtrl, page)
tabCtrl.TabPages.Remove(page)
hiddenPages.Add(TabPageData.GetKey(tabCtrl, page), tpinfo)
End If
End Sub
Public Function IsVisible(page As TabPage) As Boolean
Return page IsNot Nothing AndAlso page.Parent IsNot Nothing
' when Parent is null the tab page does not belong to any container
End Function
Public Sub CleanUpHiddenPage(page As TabPage)
For Each info As TabPageData In hiddenPages.Values
If info.Parent IsNot Nothing AndAlso info.Parent.Equals(DirectCast(page.Parent, TabControl)) Then
info.Page.Dispose()
End If
Next
End Sub
Public Sub CleanUpAllHiddenPages()
For Each info As TabPageData In hiddenPages.Values
info.Page.Dispose()
Next
End Sub
End Class
采纳答案by varocarbas
The conversion you have done of the original C# code is not perfect (you should understand what each part does, instead of copying bit by bit). In the SetVisible/SetInvisiblepart this is the problem:
你对原始C#代码所做的转换并不完美(你应该了解每个部分的作用,而不是一点一点地复制)。在SetVisible/SetInvisible部分,这是问题所在:
Public Shared Function SetInvisible(page As TabPage, frm As Form) 'As Boolean
page = frm.Controls(page.Name)
If IsVisible(page) Then
Dim tabCtrl As TabControl = DirectCast(page.Parent, TabControl)
Dim tpinfo As TabPageData
tpinfo = New TabPageData(tabCtrl.TabPages.IndexOf(page), tabCtrl, page)
tabCtrl.TabPages.Remove(page)
hiddenPages.Add(TabPageData.GetKey(tabCtrl, page), tpinfo)
End If
End Function
(this should be a Subrather than a Function) You are adding a bit not present in the original code: page = frm.Controls(page.Name); I guess that it is an adaptation to make the code work under your specific conditions (you have added to the form a TabPagealone, instead one inside a TabControl, what is the normal behaviour). This would be fine, but you are not adapting the SetVisible function to this reality:
(这应该是 aSub而不是 a Function)您正在添加原始代码中不存在的位:page = frm.Controls(page.Name); 我想这是使代码在您的特定条件下工作的一种适应(您已TabPage单独添加到表单 a 中,而不是在 a 中添加一个TabControl,正常行为是什么)。这很好,但您没有使 SetVisible 函数适应这一现实:
Public Shared Sub SetVisible(page As TabPage, parent As TabControl)
If parent IsNot Nothing AndAlso Not parent.IsDisposed Then
Dim tpinfo As TabPageData
Dim key As String = TabPageData.GetKey(parent, page)
If hiddenPages.ContainsKey(key) Then
tpinfo = hiddenPages(key)
If tpinfo.Index < parent.TabPages.Count Then
parent.TabPages.Insert(tpinfo.Index, tpinfo.Page)
Else
' add the page in the same position it had
parent.TabPages.Add(tpinfo.Page)
End If
hiddenPages.Remove(key)
Else
PrintAllKeys()
End If
End If
End Sub
Understand what both functions do: the first one (modified by you) expects a TabPage added to the form directly (thus with no parent TabControl); the second one (as in the original C# code) expects a TabPage with a parent TabControl but your input does not have that. How I know that? If your TabPage would have a TabControl as a parent, the page = frm.Controls(page.Name)would be Nothing.
了解这两个函数的作用:第一个(由您修改)期望将 TabPage 直接添加到表单中(因此没有父 TabControl);第二个(在原始 C# 代码中)需要一个带有父 TabControl 的 TabPage,但您的输入没有。我怎么知道?如果您TabPage的将有一个TabControl作为家长,该page = frm.Controls(page.Name)会Nothing。
If you want to use this code you have to provide the expected inputs, that is, TabPages inside a TabControl. Otherwise, you should modify it accordingly (not just one part, all the parts). Easy test for you to understand what is required:
如果您想使用此代码,您必须提供预期的输入,即 TabControl 中的 TabPages。否则,您应该相应地修改它(不仅仅是一部分,而是所有部分)。简单的测试让您了解需要什么:
1- Open a new project and add a new TabControl via "Design View".
2- Copy your class but let SetInvisible as in the original version (delete page = frm.Controls(page.Name)).
3- Test your class with the main form and see that it works fine. Sample code (these are the default names when you add a new TabControl):
1- 打开一个新项目并通过“设计视图”添加一个新的 TabControl。
2- 复制您的课程,但让 SetInvisible 像原始版本一样(删除page = frm.Controls(page.Name))。
3- 用主窗体测试你的类,看看它工作正常。示例代码(这些是添加 new 时的默认名称TabControl):
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim test As clsTabManager = New clsTabManager()
test.SetInvisible(TabPage1, Me)
test.SetVisible(TabPage1, TabControl1)
End Sub
回答by user5708300
I just implemented your suggested code and came up with a problem. It centers around trying to make a previously invisible tab page visible again. The problem is that once a tab page is made invisible, it no longer is part of the tab control. It is stored inside one of the TabpageDatastructures so it can later be retrieved. But, in order to make the tab page visible again, I had to modify the SetVisible()method to include the PageNameand not the Tabpage, as well as the GetKey()function to pass in the tabcontrol and the tab's name.
我刚刚实施了您建议的代码并提出了一个问题。它围绕着试图使以前不可见的标签页再次可见。问题是,一旦标签页变得不可见,它就不再是标签控件的一部分。它存储在其中一个TabpageData结构中,以便以后可以检索。但是,为了使标签页再次可见,我不得不修改SetVisible()方法以包含PageName而不是标签页,以及GetKey()传递标签控件和标签名称的函数。
Here's the new GetKey():
这是新的GetKey():
Friend Shared Function GetKey ( tabCtrl As TabControl, tabName As string ) As String
Dim key As String = ""
If tabCtrl IsNot Nothing Then
key = [String].Format( "{0}:{1}", tabCtrl.Name, tabName )
End If
Return key
End Function
And here is the new SetVisible:
这是新的SetVisible:
Public Sub SetVisible ( PageName As String, parent As TabControl )
If parent IsNot Nothing AndAlso Not parent.IsDisposed Then
Dim tpinfo As TabPageData
Dim key As String = TabPageData.GetKey ( parent, PageName )
If hiddenPages.ContainsKey(key) Then
tpinfo = hiddenPages(key)
If tpinfo.Index < parent.TabPages.Count Then
parent.TabPages.Insert(tpinfo.Index, tpinfo.Page)
Else
' add the page in the same position it had
parent.TabPages.Add(tpinfo.Page)
End If
hiddenPages.Remove(key)
End If
End If
End Sub
回答by Jim
You need to check for if a postback or not in your frmMain_Load so that it doesn't always set invisible.
您需要检查您的 frmMain_Load 中是否有回发,以便它不会总是设置为不可见。
Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If Not Page.IsPostBack Then
clsTabManager.SetInvisible(tcManaging.TabPages("tpEdit"))
End If
End Sub

