TabControl ohne Reiter

    • VB.NET

    Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von FormFollowsFunction.

      TabControl ohne Reiter

      Hier wie man die Reiter eines TabControls verstecken kann, weil manche finden die häßlich.
      Damit kann man Funktionsbereiche einer Anwendung auf verschiedene Tabs unterbringen, und etwa über ein menü oder über eine Combo-/List-Box steuern, welcher Funktionsbereich grade aktiv sein soll.

      Ich hab gleich alle 3 genannten Steuerungs-möglichkeiten implementiert, wie man sieht, macht die Steuerung per Menü etwas mehr Aufwand, da man kein Databinding anwenden kann.

      VB.NET-Quellcode

      1. Public Class frmOhneReiter
      2. Private Sub frmOhneReiter_Load(ByVal sender As Object, ByVal e As EventArgs) _
      3. Handles Me.Load
      4. tabControl1.SuspendLayout()
      5. 'um Reiter zu verbergen benötigt man die 3 folgenden Einstellungen
      6. 'ich empfehle das codeseitig zu machen, weil im Designer hat man sonst
      7. ' Probleme, die TabPages zum designen auszuwählen
      8. tabControl1.SizeMode = TabSizeMode.Fixed
      9. tabControl1.ItemSize = New Size(0, 1)
      10. tabControl1.Appearance = TabAppearance.Buttons
      11. tabControl1.ResumeLayout()
      12. 'list-/Combo-Box konfigurieren
      13. Dim pages = tabControl1.TabPages
      14. Me.listBox1.DisplayMember = "Text"
      15. Me.ComboBox1.DisplayMember = "Text"
      16. listBox1.DataSource = pages
      17. ComboBox1.DataSource = pages
      18. 'MenuItems erzeugen und konfigurieren
      19. Dim tabMenuItems = TabPageToolStripMenuItem.DropDownItems
      20. For Each tp As TabPage In pages
      21. Dim itm = DirectCast(tabMenuItems.Add(tp.Text), ToolStripMenuItem)
      22. AddHandler itm.Click, AddressOf MenuItem_Click
      23. Next
      24. DirectCast(tabMenuItems(0), ToolStripMenuItem).Checked = True
      25. End Sub
      26. Private Sub listControl_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) _
      27. Handles listBox1.SelectedIndexChanged, ComboBox1.SelectedIndexChanged
      28. tabControl1.SelectedIndex = listBox1.SelectedIndex
      29. 'TabControl ist bisserl doof - es nimmt den Focus, auch wenn nur per Code selektiert wurde
      30. listBox1.Focus() 'Focus zurück zur Listbox
      31. End Sub
      32. Private Sub MenuItem_Click(ByVal sender As Object, ByVal e As EventArgs)
      33. Dim tabMenuItems = TabPageToolStripMenuItem.DropDownItems
      34. For i = 0 To tabMenuItems.Count - 1
      35. Dim itm = DirectCast(tabMenuItems(i), ToolStripMenuItem)
      36. Dim isSelected = itm Is sender
      37. itm.Checked = isSelected
      38. If isSelected Then tabControl1.SelectedIndex = i
      39. Next
      40. End Sub
      41. End Class


      Erläuterung
      Für List- und Combo-Box wird im Load jeweils DataSource und DisplayMember festgelegt, und im listControl_SelectedIndexChanged wird ihr SelectedIndex aufs TabControl übertragen.
      Die MenüItem müssen erst codeseitig erzeugt, und per AddHandler ans MenuItem_Click angeschlossen werden.
      In MenuItem_Click muß der Index für den gewünschten TabIndex erst ermittelt werden, und auch die Checked-Property aller Items korrekt gesetz wern - naja - auch kein Act.

      Man muß sich halt für eine Steuerung entscheiden, weil so, wies hier gemacht ist, erfolgt keine Synchronisation der Listbox, wenn per Menü die Tab gewechselt wurde. Und umgekehrt auch nicht.

      Weitere Ideen, ein TabControl zu pimpen, finden sich auf erweitertes TabControl
      Dateien
      • OhneReiter00.zip

        (14,32 kB, 853 mal heruntergeladen, zuletzt: )

      TabControl ohne Reiter

      [OffTopic]
      Jetzt hatte ich doch glatt den Überblick verloren, und meinen eigenen Tipp nicht wiedergefunden, und daher neu gemacht.
      Ich hab aber nicht einfach einen löschen lassen, sondern hier zusammenführen (Dank an die Mods! :)).
      Weil die neue Variante zeigt auch die Ansteuerung der Tabs mittels "Next"/"Previous" - Buttons, welche auf den Tabs aufsitzen (Assistenten-Navigation).

      Also hier eiglich dasselbe wie oben, nochmal:
      [/OffTopic]



      Mittm TabControl kann man die Funktionalität einer komplexen Anwendung in sinnvolle übersichtliche Einheiten strukturieren, ohne dass man viele Dialoge aufpoppen lassen müsste.

      Gelegentlich will man sich aber auch sowas wie einen Assistenten basteln, also eine Anwendung, die eine Ansicht nach der anneren nacheinander präsentiert, und wo man vor- und zurück-navigieren kann - Assistenten-Navigation.

      Oder man hat eine Treeview oder Listbox, und je nach angewähltem Item benötigt man eine annere Ansicht - Frameset-Navigation.

      Auch für diese Anforderungen eignet sich TabControl. Man muß nur die Reiter verstecken, dann hat man damit ein Dingsbums mit vielen Panels, die man nach Belieben nach vorne holen kann (.SelectedIndex setzen oder .SelectedTab)
      Dabei erhält man sogar den Komfort, dass die Reiter nur zur Laufzeit verschwinden - zum Designen kann man ganz normal zwischen den Tabs wechseln, und seine Controls aufbringen.

      Anbei ein Sample, was die genannten 3 Möglichkeiten der Navigation aufzeigt:
      1. standard-Navigation mittels der Reiter
      2. versteckte Reiter - Assistenten-Navigation durch Vor- und Zurück-Buttons
      3. versteckte Reiter - Frameset-Navigation über Anwahl von Listbox-Items

      VB.NET-Quellcode

      1. Public Class frmOhneReiter
      2. Private Sub frmOhneReiter_Load(ByVal sender As Object, ByVal e As EventArgs) _
      3. Handles MyBase.Load
      4. lstFramesetNavi.DataSource = TabControl2.TabPages.Cast(Of TabPage)().ToList
      5. lstFramesetNavi.DisplayMember = "Text"
      6. For Each tc In {TabControl2, TabControl3}
      7. With tc
      8. .SuspendLayout()
      9. 'diese 3 Einstellungen verstecken die Reiter erst zur Laufzeit
      10. 'bei Design-Arbeiten am Form sind die Reiter ja sehr nützlich
      11. .SizeMode = TabSizeMode.Fixed
      12. .ItemSize = New Size(0, 1)
      13. .Appearance = TabAppearance.Buttons
      14. .ResumeLayout()
      15. End With
      16. Next
      17. End Sub
      18. Private Sub WizzardNaviButton_Click(ByVal sender As Object, ByVal e As EventArgs) _
      19. Handles btNext6.Click, btPrev7.Click, btNext7.Click, btPrev8.Click
      20. Select Case True
      21. Case sender Is btNext6, sender Is btNext7
      22. TabControl3.SelectedIndex += 1
      23. Case sender Is btPrev7, sender Is btPrev8
      24. TabControl3.SelectedIndex -= 1
      25. End Select
      26. End Sub
      27. Private Sub lstFramesetNavi_SelectedIndexChanged(ByVal sender As Object, ByVal e As EventArgs) _
      28. Handles lstFramesetNavi.SelectedIndexChanged
      29. TabControl2.SelectedIndex = lstFramesetNavi.SelectedIndex
      30. End Sub
      31. End Class
      Dateien
      • OhneReiter00.zip

        (15,04 kB, 577 mal heruntergeladen, zuletzt: )

      Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „ErfinderDesRades“ ()

      TreeviewFrameset

      Hier noch eine Variante, wo die Tabs nicht per Menü, Combo oder Listbox gesteuert werden, sondern über einen Treeview. Das mag angezeigt sein bei extrem vielen TabPages, welche man in sinnvolle Gruppen gruppieren möchte.
      Zu beachten, dass die Gruppen-Treenodes keiner TabPage zugeordnet sind, sondern nur diejenigen Nodes addressieren einen Tab, welche keine Childnodes haben ("Blätter").
      Ich hab einen Spezial-Treeview dafür gecodet, der eine "TabControl"-Property aufweist. Dieser Property kann man im Designer ein TabControl zuweisen, und noch im Designer überträgt der Treeview seine Knoten-Beschriftungen auf die Tabs des TabControls.

      Zur Designzeit kann der Treeview natürlich keine Tabs auswählen, und deshalb werden die Beschriftungen übertragen.
      Man gestaltet also die Treenodes im Designer, und wirft einen Haufen Tabpages ins Tabcontrol. Indem man dann (immer noch im Designer) die TabControl-Property des Treeviews festlegt, setzt man dadurch die Tab-Beschriftungen, anhand derer man sich bei der Gestaltung der Tabpages orientieren kann.
      Bei der Zuordnung ist allein die Reihenfolge der Tabpages maßgeblich. Ändert man die Reihenfolge, so bügelt der Treeview seine Beschriftungen gnadenlos drüber, sodass u.U. mehrere Beschriftungen gleichzeitig geändert werden.
      Eine Neu-Beschriftung löst man aus, indem man die FramesetTreeview.Tabcontrol-Property auf "(keine)" setzt, und dann wieder aufs Tabcontrol.
      Es wären auch ganz annere Konzepte von Zuordnung denkbar gewesen: Etwa dass man die Zuordnungen in einer gesonderten Datei festlegt. Oder dass man Zuordnungs-Informationen in die Tag-Property der TabPages schreibt.
      Aber sowas wäre mit Sicherheit wesentlich umständlicher zu benutzen als meine Lösung, wo man einfach den Treeview-Editor des VisualStudios verwenden kann, um die Struktur zu organisieren.
      Also das Ergebnis zur Laufzeit ist nicht sonderlich berühmt, aber man kann erkennen, das die richtige Tabpage selectiert wurde.

      Bitte viel testen, weil bei der Entwicklung von Controls finde ich das Designer-Verhalten immer sehr unkalkulierbar. ZB der FramesetTreeview ist davon abhängig, dass der Designer-Code zuerst die Treenodes generiert, und danach die TabControl-Zuweisung. Das scheint zwar hinzuhauen, aber vlt. sind ja auch Konstellationen möglich, wo die Treenodes erst hinterher geadded werden - ich weiß es nicht.

      FramesetTreeview-Code

      VB.NET-Quellcode

      1. Imports System.ComponentModel
      2. <DesignerCategory("code")> _
      3. Public Class FramesetTreeView : Inherits TreeView
      4. Private _TabControl As TabControl
      5. Public Property TabControl As TabControl
      6. Get
      7. Return _TabControl
      8. End Get
      9. Set(value As TabControl)
      10. _TabControl = value
      11. If _TabControl Is Nothing Then Return
      12. If Not DesignMode Then Return
      13. 'im Designmode wird der Treeview rekursiv durchlaufen, und den tabs wird die Beschriftung derjenigen Nodes zugewiesen, die keine ChildNodes haben
      14. Dim i = 0
      15. Dim tabs = _TabControl.TabPages
      16. Dim recurse As Action(Of TreeNodeCollection) = Sub(nodes As TreeNodeCollection)
      17. For Each nd As TreeNode In nodes
      18. If i >= tabs.Count Then Return
      19. If nd.Nodes.Count = 0 Then
      20. tabs(i).Text = nd.Text
      21. i += 1
      22. Else
      23. recurse(nd.Nodes)
      24. End If
      25. Next
      26. End Sub
      27. recurse(Nodes)
      28. For i = i To tabs.Count - 1
      29. tabs(i).Text = tabs(i).Name
      30. Next
      31. End Set
      32. End Property
      33. Protected Overrides Sub OnAfterSelect(e As System.Windows.Forms.TreeViewEventArgs)
      34. If e.Node.Nodes.Count = 0 Then
      35. Dim count = 0
      36. Dim done = False
      37. 'rekursiv wird der SelectedNode gesucht - dabei werden die Nodes ohne Childnodes gezählt.
      38. Dim recurse As Action(Of TreeNodeCollection) = Sub(nodes As TreeNodeCollection)
      39. For Each nd As TreeNode In nodes
      40. If done Then Return
      41. If nd.Nodes.Count = 0 Then
      42. If nd Is e.Node Then
      43. done = True
      44. Return
      45. End If
      46. count += 1
      47. Else
      48. recurse(nd.Nodes)
      49. End If
      50. Next
      51. End Sub
      52. recurse(Nodes)
      53. _TabControl.SelectedIndex = count 'count ist der Index des assoziierten tabs
      54. Me.Focus()
      55. End If
      56. MyBase.OnAfterSelect(e)
      57. End Sub
      58. End Class


      Hinweis zum Download:
      Der Designer kann das Form erst darstellen, nachdem die Solution kompiliert wurde (Menü - "Erstellen" - "Projektmappe neu erstellen")
      Oder einfach F5 drücken.
      Dateien

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

      Hallo,

      ich habe da mal ne Frage/Antwort.
      Wäre es nicht einfacher sich einfach ein eigenes UserControl/Control zu kompilieren bzw. eine Klasse zu erstellen, die von TabControl erbt?

      Sähe dann so aus:

      VB.NET-Quellcode

      1. Friend Class TablessTabControl
      2. Inherits TabControl
      3. Private Const TCM_ADJUSTRECT As Integer = &H1328
      4. Protected Overrides Sub WndProc(ByRef m As Message)
      5. ' Hide the tab headers at run-time
      6. If m.Msg = TCM_ADJUSTRECT AndAlso Not DesignMode Then
      7. m.Result = DirectCast(1, IntPtr)
      8. Return
      9. End If
      10. ' call the base class implementation
      11. MyBase.WndProc(m)
      12. End Sub
      13. End Class


      bzw.

      C#-Quellcode

      1. internal class TablessTabControl : TabControl
      2. {
      3. private const int TCM_ADJUSTRECT = 0x1328;
      4. protected override void WndProc(ref Message m)
      5. {
      6. // Hide the tab headers at run-time
      7. if (m.Msg == TCM_ADJUSTRECT && !DesignMode)
      8. {
      9. m.Result = (IntPtr)1;
      10. return;
      11. }
      12. // call the base class implementation
      13. base.WndProc(ref m);
      14. }
      15. }


      Dazu müsste man nur eine Klasse hinzufügen und den Code einfügen, dann das Projekt erstellen/debuggen, aus der Toolbox auf die Form ziehen und zack, ein neues TabControl ohne Tabs. Ein Vorteil ist hierbei, dass diese nur zur Laufzeit ausgeblendet werden, im Designer ist alles aktiv.

      Grüße
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      Sorry, ich hatte das mal vor längerer Zeit für mein Projekt von Stackoverflow übernommen und habe es jetzt deshalb so angegeben.
      Deshalb ist es ja auch frei zur Verfügung, aber ok, wenn jemand die Source haben will ;)
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      Wäre es nicht einfacher sich einfach ein eigenes UserControl/Control zu kompilieren bzw. eine Klasse zu erstellen, die von TabControl erbt?
      Einfacher ists nicht, weil man braucht eine Extra-Klasse, wo ich nur 4 Zeilen brauche, die ich zB auch als Tabcontrol-Extension formulieren könnte, und dann wäre Tablessness ein Feature jedes' Tabcontrols :P .

      Aber was mir an dem Teil gefällt, ist, dass der Rand drumrum schmaler ist.
      Der ist bei meinem Ansatz ziemlich breit, und ist meist nicht erwünscht, aber afaik nicht wegzukriegen.
      @Trade : Kurze Frage, gibts zufällig auch ne WindowsMessage um diese kleine scrollbar auszubelenden die auftaucht wenn man viele TabPages hat:

      Unnötiges Vollzitat entfernt
      -Artentus
      C# Developer
      Learning C++

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Artentus“ ()

      Moin,

      das Problem hatte ich auch schon, bisher aber noch keine Lösung gefunden, weil das TabControl hierfür nicht flexibel genug ist.
      Sollte jemand eine Lösung haben, wäre es toll, wenn er sie hier mit uns teilen könnte. ;)

      Grüße
      #define for for(int z=0;z<2;++z)for // Have fun!
      Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

      Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
      @Rikudo
      @Trade
      Ganz einfach weg bekommen kann man sie soweit ich weiß nicht, man kann jedoch die Tabs auf mehrere Zeilen aufteilen, indem man ​TCS_MULTILINE setzt.

      Und wenn wir schon grad bei sonstigem TabControl-Zeugs sind:
      Mit ​TCS_RIGHTJUSTIFY sorgt man dafür, dass sich die Tab-Header auf die komplette Breite erstrecken - finde den Effekt ganz nett.

      Tabcontrol mit Reiter - einzelne TabPages verstecken

      @RodFromGermany behauptet hier, einen Weg dafür gefunden zu haben: nämlich die TabPageCollection leeren, dann aber die TabPages, die man behalten will, wieder hinmachen:

      RodFromGermany schrieb:

      @ErfinderDesRades Jetzt hab ich es gefunden:

      C#-Quellcode

      1. this.tabControl1.TabPages.Clear(); // leert nur die Collection, die TabPages bleiben erhalten
      2. this.tabControl1.TabPages.Add(this.tc1); // die Collection mit den erforderlichen Pages neu aufbauem
      3. this.tabControl1.TabPages.Add(this.tc3);
      4. this.tabControl1.TabPages.Add(this.tc5);

      (Ich übernehme das (erstmal ungeprüft) hierher, damit ich's bei Bedarf wiederfinde)
      Ich hab das hier in meinen DLLs drinne. Funktioniert auch.

      VB.NET-Quellcode

      1. Private Class TabPageSettings
      2. Public TabPage As TabPage = Nothing
      3. Public ContainingTabControl As TabControl = Nothing
      4. End Class
      5. Private ReadOnly ListOfTabPages As New List(Of TabPageSettings)
      6. <Extension> Public Sub ShowTab(TabPage As TabPage)
      7. Dim FittingTabPageSettings = ListOfTabPages.FirstOrDefault(Function(x) x.TabPage Is TabPage)
      8. If FittingTabPageSettings IsNot Nothing AndAlso Not FittingTabPageSettings.ContainingTabControl.TabPages.Contains(TabPage) Then FittingTabPageSettings.ContainingTabControl.TabPages.Add(TabPage)
      9. End Sub
      10. <Extension> Public Sub HideTab(TabPage As TabPage)
      11. If TabPage.Parent Is Nothing Then Return
      12. Dim TabControl = DirectCast(TabPage.Parent, TabControl)
      13. If Not TabControl.TabPages.Contains(TabPage) Then Return
      14. TabControl.TabPages.Remove(TabPage)
      15. ListOfTabPages.Add(New TabPageSettings With {.ContainingTabControl = TabControl, .TabPage = TabPage})
      16. End Sub


      ##########

      eigene Extensions durch .NET-Varianten ersetzt
      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

      Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „VaporiZed“ ()

      Da ich selber mal wieder ein TabControl zur Hand nehme und über das Problem gestolpert bin, dass man die TabPages auch bei einem TabControl ohne Reiter mit Strg+BildAuf/Strg+BildAb/Strg+Tab wechseln kann, obwohl das vom Programmierer wahrscheinlich nicht gewollt ist, hab ich grad festgestellt, dass das mit meinen Extensions gut zu lösen ist. Man stellt das TabControl mithilfe der von EdR genannten Einstellungen auf reiterlos, versteckt alle TabPages mithilfe der im Vorpost genannten HideTab-Extension bis auf die einzige anzuzeigende Page und zeigt dann im Programmverlauf z.B. mit Buttons die TabPage an, die man sehen will und versteckt alle anderen.
      Das Projekt im Anhang ist etwas ausgebaut, damit man nicht alle Pages einzeln toggeln muss.
      Dateien
      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

      Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
      @VaporiZed Ich hab mal reingeschaut.
      Wenn Du Dir über die TabPage deren Parent holst und das alles (TabControl und TabPages) in Klassenvariablen speicherst, wäre es nicht einfacher, dafür eine von TabPage abgeleitete Klasse zu schreiben?
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      Das ist richtig, aber ich belasse Controls meistens gerne so, wie sie sind. Der eine so, der andere so. Aber es spräche nix dagegen, eine dementsprechende Klasse zu generieren.
      Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

      Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
      Hier mal beide Lösungen in einem Projekt, Umschaltung durch Auswahl der Startform in den Projekteigenschaften.
      TabControl ohne Reiter und Navigationsumgebung2.zip
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      Programmierfragen über PN / Konversation werden ignoriert!
      Hier noch eine Variante:
      Die Navigationsumgebung fange ich im KeyDown Ereignis ab, finde ich eleganter als an der TabPageCollection rum zu fummeln.
      Und weil ich schonmal da war, habe ich noch ein paar Methoden zu selektieren eingebaut.

      VB.NET-Quellcode

      1. Public Class TabControlEx
      2. Inherits TabControl
      3. Sub New()
      4. DisableNavigationKeys = True
      5. End Sub
      6. #Region "Hide Tab's At Runtime"
      7. Private Const TCM_ADJUSTRECT As Integer = &H1328
      8. Protected Overrides Sub WndProc(ByRef m As Message)
      9. If Not DesignMode AndAlso m.Msg = TCM_ADJUSTRECT Then
      10. m.Result = CType(1, IntPtr)
      11. Return
      12. End If
      13. MyBase.WndProc(m)
      14. End Sub
      15. #End Region
      16. #Region "Disable Control Navigation Logig"
      17. Private _DisableNavigationKeys As Boolean
      18. Public Property DisableNavigationKeys() As Boolean
      19. Get
      20. Return _DisableNavigationKeys
      21. End Get
      22. Set(value As Boolean)
      23. _DisableNavigationKeys = value
      24. Select Case _DisableNavigationKeys
      25. Case True
      26. RemoveHandler KeyDown, AddressOf Me_KeyDown
      27. AddHandler KeyDown, AddressOf Me_KeyDown
      28. Case False
      29. RemoveHandler KeyDown, AddressOf Me_KeyDown
      30. End Select
      31. End Set
      32. End Property
      33. Private Sub Me_KeyDown(sender As Object, e As KeyEventArgs)
      34. e.SuppressKeyPress =
      35. e.KeyCode = Keys.Left OrElse
      36. e.KeyCode = Keys.Right
      37. End Sub
      38. #End Region
      39. #Region "Custom Navigation"
      40. Public Sub SelectNextTabPage()
      41. Dim selectedTabIndex As Integer = TabPages.IndexOf(SelectedTab)
      42. If selectedTabIndex = TabPages.Count - 1 Then
      43. selectedTabIndex = 0
      44. Else
      45. selectedTabIndex = selectedTabIndex + 1
      46. End If
      47. SelectedTab = TabPages(selectedTabIndex)
      48. End Sub
      49. Public Sub SelectBeforeTabPage()
      50. Dim selectedTabIndex As Integer = TabPages.IndexOf(SelectedTab)
      51. If selectedTabIndex = 0 Then
      52. selectedTabIndex = TabPages.Count - 1
      53. Else
      54. selectedTabIndex = selectedTabIndex - 1
      55. End If
      56. SelectedTab = TabPages(selectedTabIndex)
      57. End Sub
      58. Public Sub SelectFirstTabPage()
      59. SelectedTab = TabPages(0)
      60. End Sub
      61. Public Sub SelectLastTabPage()
      62. SelectedTab = TabPages(TabPages.Count - 1)
      63. End Sub
      64. #End Region
      65. End Class
      Dateien