Скрытие и отображение вкладок в VB .NET - TabManager
Я пытаюсь динамически скрывать и показывать вкладки во время выполнения. Для этого я преобразовал код Эмиля отсюда в vb.net, и в результате проблема в том, что вкладки больше не могут быть показаны после того, как они были скрыты. По крайней мере, если бы они были установлены как невидимые где-то еще, чем где я пытаюсь сделать их видимыми.
редактировать:
После долгого обсуждения я наконец-то получил рабочий результат. я исправил процедуры вызова, и теперь этот код работает. Он может скрывать и отображать вкладки, которые находятся в любой форме, как и в оригинальной версии. Спасибо перейти к пользователю 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 ответа
Преобразование исходного кода 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
,
Если вы хотите использовать этот код, вы должны предоставить ожидаемые входные данные, то есть TabPages внутри TabControl. В противном случае вы должны изменить его соответствующим образом (не только одну часть, все части). Простой тест для вас, чтобы понять, что требуется:
1- Откройте новый проект и добавьте новый TabControl через "Design View".
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
Я только что реализовал предложенный вами код и обнаружил проблему. Он сосредотачивается вокруг попыток сделать ранее невидимую закладку снова видимой. Проблема заключается в том, что после того, как вкладка становится невидимой, она больше не является частью элемента управления вкладкой. Он хранится внутри одного из 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
Вам нужно проверить, есть ли постбэк или нет в вашем 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