在VB .NET中隐藏和显示TabPages - TabManager

时间:2013-08-05 12:22:04

标签: .net vb.net tabcontrol tabpage

我尝试在运行时动态隐藏和显示tabpages。为此,我将Emile的代码从here转换为vb.net,结果出现的问题是,隐藏页面后,tabpages不再显示。至少不会,如果它们被设置为隐藏在其他地方,而不是我尝试将它们设置为可见。

编辑:

经过长时间的讨论,我终于得出了一份工作成果。我纠正了调用程序,现在这段代码有效。它可以隐藏和显示驻留在任何表单上的tabpages,就像original version一样。谢谢你去用户varocarbas ..

隐藏标签页:

clsTabManager.SetInvisible(tabPage)

显示标签页(从任何类/表单调用):

clsTabManager.SetVisible(FormWithTabControl.tabPage, FormWithTabControl.TabControl)

显示标签页(从TabControl 所在的表格中调用):

clsTabManager.SetVisible(tabPage, TabControl)

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

3 个答案:

答案 0 :(得分:1)

您对原始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

(这应该是Sub而不是Function)您正在添加原始代码中不存在的位:page = frm.Controls(page.Name);我想这是一个改编,使代码在您的特定条件下工作(您已经单独添加到表单TabPage,而在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

理解这两个函数的作用:第一个函数(由你修改)期望一个TabPage直接添加到表单中(因此没有父TabControl);第二个(如在原始C#代码中)期望TabPage与父TabControl,但您的输入没有。我怎么知道的?如果您的TabPage将TabControl作为父级,则page = frm.Controls(page.Name)将为Nothing

如果要使用此代码,则必须提供预期的输入,即TabControl中的TabPages。否则,您应该相应地修改它(不只是一个部分,所有部分)。轻松测试,了解所需内容:

1-打开一个新项目并通过“Design View”添加一个新的TabControl 2-复制您的课程,但让SetInvisible与原始版本一样(删除page = frm.Controls(page.Name)) 3-使用主窗体测试您的课程,看看它是否正常工作。示例代码(这些是添加新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

答案 1 :(得分:1)

我刚刚实施了您建议的代码,并提出了一个问题。它的核心是尝试再次显示以前不可见的标签页。问题是,一旦标签页变得不可见,它就不再是标签控件的一部分。它存储在TabpageData结构中的一个中,以便以后可以检索。但是,为了使标签页再次可见,我必须修改SetVisible()方法以包含PageName而不是标签页,以及GetKey()函数来传递tabcontrol和标签的名称。

这里是新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

这是新的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

答案 2 :(得分:0)

您需要检查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