1

実行時にタブページを動的に非表示および表示しようとしています。このために、Emile のコードをhereから 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

提案されたコードを実装したところ、問題が発生しました。これは、以前は非表示だったタブ ページを再び表示できるようにすることを中心にしています。問題は、タブ ページが非表示になると、タブ コントロールの一部ではなくなることです。TabpageData後で取得できるように、いずれかの構造内に格納されます。しかし、タブ ページを再び表示するには、Tabpage ではなくSetVisible()を含めるようにメソッドを変更し、タブ コントロールとタブの名前を渡す関数も変更する必要がありました。PageNameGetKey()

これが新しいもの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 に答える
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); 特定の条件下でコードを機能させるための適応だと思います(通常の動作とは、TabPagea の代わりに 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 はありません)。2番目のもの(元のC#コードのように)は、親TabControlを持つTabPageを期待していますが、入力にはそれがありません。どうやってそれを知っていますか?TabPage が親として TabControl を持つ場合、 はpage = frm.Controls(page.Name)になりますNothing

このコードを使用する場合は、予期される入力、つまり、TabControl 内の TabPages を提供する必要があります。それ以外の場合は、それに応じて変更する必要があります (1 つの部分だけでなく、すべての部分)。何が必要かを理解するための簡単なテスト:

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 に答える
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 に答える