1

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

编辑:

经过长时间的讨论,我终于想出了一个工作结果。我更正了调用程序,现在这段代码可以工作了。它可以隐藏和显示驻留在任何表单上的标签页,就像原始版本一样。感谢用户 varocarbas..

隐藏标签页:

clsTabManager.SetInvisible(tabPage)

显示一个标签页(来自任何类/表单的调用):

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

显示一个标签页(从 TabControl所在的 Form 调用):

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
4

3 回答 3

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

(这应该是 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

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

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

1- 打开一个新项目并通过“设计视图”添加一个新的 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
于 2013-08-05T15:50:14.483 回答
1

我刚刚实现了您建议的代码并提出了一个问题。它的中心是试图使以前不可见的标签页再次可见。问题是一旦标签页变为不可见,它就不再是标签控件的一部分。它存储在其中一个TabpageData结构中,以便以后可以检索它。但是,为了使标签页再次可见,我不得不修改SetVisible()方法以包含PageName而不是标签页,以及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

这是新的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
于 2015-12-22T17:46:29.150 回答
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
于 2013-08-05T15:48:22.683 回答