Die Community zu .NET und Classic VB.
Menü

Tipp-Upload: VB.NET 0274: erweitertes TabControl

 von 

Über den Tipp  

Dieser Tippvorschlag ist noch unbewertet.

Der Vorschlag ist in den folgenden Kategorien zu finden:

  • Steuerelemente

Dem Tippvorschlag wurden folgende Schlüsselwörter zugeordnet:
Ownerdrawing

Der Vorschlag wurde erstellt am: 16.05.2008 15:06.
Die letzte Aktualisierung erfolgte am 27.11.2008 15:48.

Zurück zur Übersicht

Beschreibung  

Tabpage-Selektion bei Maus_Over überm Reiter, Farbanpassung des Reiters an die Tabpage, Möglichkeit, Tabpages zu disablen, RiderClicked-Event
Außerdem wird gezeigt, wie man auch beim normalen TabControl die Reiter versteckt.

Schwierigkeitsgrad

Schwierigkeitsgrad 2

Verwendete API-Aufrufe:

Download:

Download des Beispielprojektes [14,34 KB]

' Dieser Source stammt von http://www.activevb.de
' und kann frei verwendet werden. Für eventuelle Schäden
' wird nicht gehaftet.

' Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
' Ansonsten viel Spaß und Erfolg mit diesem Source!
'
' Beachten Sie, das vom Designer generierter Code hier ausgeblendet wird.
' In den Zip-Dateien ist er jedoch zu finden.

' ----------- Anfang Projektgruppe TabControlX.sln -----------
' ---------- Anfang Projektdatei TabControlX.vbproj ----------
' --------------- Anfang Datei TabControlEx.vb ---------------
' IDE-Voreinstellungen:
' Option Strict On
' Option Explicit On

Imports System.ComponentModel

''' <summary>
''' erweitertes TabControl: Tabpage-Selektion wenn Maus überm Reiter, Farbanpassung des
''' Reiters an die Tabpage, Möglichkeit, Tabpages zu disablen, RiderClicked-Event
''' </summary>
Public Class TabControlEx

    Inherits TabControl

    Public Class RiderClickedEventArgs

        Inherits EventArgs

        Public ReadOnly TabPage As TabPage
        Public ReadOnly Index As Integer

        Public Sub New(ByVal Index As Integer, ByVal TabPage As TabPage)

            Me.Index = Index
            Me.TabPage = TabPage

        End Sub

    End Class

    ' Da die TabPages schon in OnMouseMove selektiert werden, ist der Klick auf die Reiter frei,
    ' um als User-Eingabe ausgewertet zu werden - man gewinnt quasi einen Button auf dem Reiter
    Public Event RiderClicked As EventHandler(Of RiderClickedEventArgs)

    Private _Brush As New SolidBrush(Color.AliceBlue)
    Private ReadOnly _Disableds As New List(Of Control)

    Public Sub New()

        Me.DrawMode = TabDrawMode.OwnerDrawFixed

    End Sub

    Protected Overrides Sub OnClick(ByVal e As EventArgs)

        ' MyBase.OnClick(e)                                 'Original-Click deaktivieren
        Dim Indx As Integer = GetTabRider(Me.PointToClient(Control.MousePosition))

        If Indx < 0 OrElse Not IsTabEnabled(Indx) Then Return
        RaiseEvent RiderClicked(Me, New RiderClickedEventArgs(Indx, TabPages(Indx)))

    End Sub

    Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)

        MyBase.OnMouseMove(e)

        Dim Indx As Integer = GetTabRider(e.Location)

        If Indx < 0 OrElse Me.SelectedIndex = Indx OrElse Not IsTabEnabled(Indx) Then Return
        Me.SelectedIndex = Indx

    End Sub

    Protected Overrides Sub OnSelecting(ByVal e As TabControlCancelEventArgs)

        If e.TabPage IsNot Nothing Then e.Cancel = _Disableds.Contains(e.TabPage)
        MyBase.OnSelecting(e)

    End Sub

    Protected Overrides Sub Dispose(ByVal disposing As Boolean)

        If disposing Then
            _Brush.Dispose()
        End If

        MyBase.Dispose(disposing)

    End Sub

    ''' <summary>zeichnet die Reiter im Stil der zugehörigen Tabpage</summary>
    Protected Overrides Sub OnDrawItem(ByVal e As System.Windows.Forms.DrawItemEventArgs)

        MyBase.OnDrawItem(e)

        Const tff As TextFormatFlags = TextFormatFlags.HorizontalCenter Or _
            TextFormatFlags.VerticalCenter

        Dim tp As TabPage = MyBase.TabPages(e.Index)
        Dim rct As Rectangle = e.Bounds
        Dim g As Graphics = e.Graphics

        If _Disableds.Contains(tp) Then
            _Brush.Color = SystemColors.Control
            g.FillRectangle(_Brush, rct)
            ControlPaint.DrawStringDisabled(g, tp.Text, Me.Font, Color.White, rct, tff)

        Else

            _Brush.Color = tp.BackColor
            g.FillRectangle(_Brush, rct)
            TextRenderer.DrawText(g, tp.Text, Me.Font, rct, tp.ForeColor, tff)
        End If

    End Sub

    Private Function GetTabRider(ByVal Pt As Point) As Integer

        For I As Integer = 0 To Me.TabPages.Count - 1

            If Me.GetTabRect(I).Contains(Pt) Then Return I
        Next

        Return -1

    End Function

    Public Property IsTabEnabled(ByVal Index As Integer) As Boolean
        Get
            Return Not _Disableds.Contains(MyBase.TabPages(Index))

        End Get

        Set(ByVal Value As Boolean)
            IsTabEnabled(MyBase.TabPages(Index)) = Value

        End Set

    End Property

    Public Property IsTabEnabled(ByVal Tp As TabPage) As Boolean
        Get
            Return Not _Disableds.Contains(Tp)

        End Get

        Set(ByVal Value As Boolean)

            If _Disableds.Contains(Tp) <> Value Then Return

            ' Trick: "TabPage.Enabled" ist in der Intellisense gar nicht
            ' vorhanden. Trotzdem ist sie da (von Control geerbt), und verwendbar
            Tp.Enabled = Value

            If Value Then
                _Disableds.Remove(Tp)

            Else

                _Disableds.Add(Tp)
            End If

            Me.Invalidate(New Rectangle(0, 0, Me.Width, Me.GetTabRect(0).Height))

        End Set

    End Property

End Class

' ---------------- Ende Datei TabControlEx.vb ----------------
' ----------------- Anfang Datei frmMain.vb  -----------------
Public Class frmMain

    Private Sub Form_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load

        For I As Integer = 0 To 2
            Me.ListBox1.SelectedIndices.Add(I)
        Next

    End Sub

    Private Sub ListBox1_MouseClick(ByVal sender As Object, ByVal e As MouseEventArgs) _
                Handles ListBox1.MouseClick

        Dim Indx As Integer = ListBox1.IndexFromPoint(e.Location)

        ' Bei Indx=3 Fehler provozieren
        ' Es kann auch auftreten, daß IsTabEnabled schon den Wert hat, der zugewiesen
        ' wird - Betrachten Sie es als Zustand, der auch ausprobiert werden will ;)
        Me.TabControlX1.IsTabEnabled(Indx) = ListBox1.GetSelected(Indx)

    End Sub

    Private Sub TabControlX1_RiderClicked( _
              ByVal sender As Object, ByVal e As TabControlEx.RiderClickedEventArgs) _
              Handles TabControlX1.RiderClicked

        Me.TabControlX1.IsTabEnabled(e.TabPage) = False

    End Sub

    Private Sub ckHideTabs_CheckedChanged(ByVal sender As Object, ByVal e As EventArgs) _
              Handles ckHideTabs.CheckedChanged

        ' interessantes Feature des normalen Tabcontrols: Man kann die Reiter verstecken!
        With Me.TabControlX1

            If ckHideTabs.Checked Then
                .SizeMode = TabSizeMode.Fixed
                .ItemSize = New Size(0, 1)
                .Appearance = TabAppearance.Buttons

            Else

                .SizeMode = TabSizeMode.Normal
                .ItemSize = New Size(60, 21)
                .Appearance = TabAppearance.Normal
            End If

        End With

    End Sub

    Private Sub btEnableAll_Click(ByVal sender As Object, ByVal e As EventArgs) Handles _
        btEnableAll.Click

        For I As Integer = 0 To 2
            Me.TabControlX1.IsTabEnabled(I) = True
        Next

    End Sub

End Class

' ------------------ Ende Datei frmMain.vb  ------------------
' ----------- Ende Projektdatei TabControlX.vbproj -----------
' ------------ Ende Projektgruppe TabControlX.sln ------------

	

Diskussion  

Diese Funktion ermöglicht es, Fragen, die die Veröffentlichung des Tipps betreffen, zu klären, oder Anregungen und Verbesserungsvorschläge einzubringen. Nach der Veröffentlichung des Tipps werden diese Beiträge nicht weiter verlinkt. Allgemeine Fragen zum Inhalt sollten daher hier nicht geklärt werden.

Um eine Diskussion eröffnen zu können, müssen sie angemeldet sein.