Contrôle des onglets verticaux avec texte horizontal dans Winforms

j'aimerais que les onglets de mon TabControl s'affichent à gauche, ou parfois à droite.

À la différence du Système.Windows.Forme.TabControl, cependant, je voudrais que le texte reste horizontal au lieu d'être tourné de 90 ou 270 degrés à l'horizontale.

Voici quelques photos illustrant le concept Vertical tabs in Visual StudioVertical tabs in Firefox

bien que je puisse écrire le code pour le faire moi-même dans environ une heure ou deux, je juste j'ai pensé demander d'abord s'il est existant Winforms contrôle qui implémente cette fonctionnalité.

NB: toute solution existante devrait de préférence être non commerciale.

Merci.

15
demandé sur Alex Essilfie 2011-09-21 14:43:06

4 réponses

Je ne sais pas à quel point c'est robuste et je ne peux pas prétendre l'avoir créé mais... http://www.dreamincode.net/forums/topic/125792-how-to-make-vertical-tabs/

Voici une façon de le faire.

donc d'abord nous allons changer son alignement à gauche, en définissant la propriété:

Alignement = Gauche

si vous avez des thèmes XP activés, alors vous pouvez remarquer la mise en page bizarre du contrôle des onglets. Ne vous inquiétez pas, nous allons faire fin.

comme vous avez peut-être remarqué que les onglets sont verticaux, et que notre exigence est horizontale. Donc on peut changer la taille des onglets. Mais avant de faire cela, nous devons définir la propriété SizeMode comme,

SizeMode = Fixed

maintenant nous pouvons changer la taille en utilisant la propriété ItemSize,

ItemSize = 30, 120 Largeur = 30 et Hauteur = 120

après avoir réglé L'alignement = Left, Tab control tourne le Les onglets qui provoquent la largeur et la hauteur semblent être inversés. C'est pourquoi, lorsque nous augmenter la Hauteur, nous voyons que la largeur augmente et lorsque l'on augmente la largeur, la hauteur est effectué.

maintenant le texte sera aussi affiché, mais verticalement. Malheureusement, il n'existe pas de solution simple à ce problème. Pour cela, nous devons écrire le texte nous-mêmes. Pour ce faire, nous allons d'abord définir le mode de dessin

DrawMode = Owndrawfixed

01

Private Sub TabControl1_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles TabControl1.DrawItem
    Dim g As Graphics
    Dim sText As String

    Dim iX As Integer
    Dim iY As Integer
    Dim sizeText As SizeF

    Dim ctlTab As TabControl

    ctlTab = CType(sender, TabControl)

    g = e.Graphics

    sText = ctlTab.TabPages(e.Index).Text
    sizeText = g.MeasureString(sText, ctlTab.Font)

    iX = e.Bounds.Left + 6
    iY = e.Bounds.Top + (e.Bounds.Height - sizeText.Height) / 2

    g.DrawString(sText, ctlTab.Font, Brushes.Black, iX, iY)
End Sub
21
répondu Rob P. 2011-09-21 14:35:21

j'ai décidé de partager le code que j'ai développé depuis certaines personnes, telles que Amit Andharia qui voudraient en bénéficier.

C'est le résultat après que j'ai implémenté réponse de Rob P..

Vertical Tabs Control screenshot

Notes:

  • Plein moment de la conception de soutien
  • redimensionnement Automatique des onglets (jusqu'à 128px de large)
  • Onglet icônes mise en œuvre
  • les propriétés non utilisées ont été cachées

le code peut être téléchargé à partir de ici.

4
répondu Alex Essilfie 2017-05-23 12:26:05

C'est le code d'un contrôle d'onglet personnalisé que j'aime beaucoup. Vous devrez copier et coller ce code dans une nouvelle classe puis reconstruire le projet. Vous verrez un nouveau contrôle d'utilisateur personnalisé s'afficher dans votre boîte à outils.

Vertical Tab Control with Indicator and ImageList

    Imports System.Drawing.Drawing2D
Class DotNetBarTabcontrol
    Inherits TabControl

    Sub New()
        SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.ResizeRedraw Or ControlStyles.UserPaint Or ControlStyles.DoubleBuffer, True)
        DoubleBuffered = True
        SizeMode = TabSizeMode.Fixed
        ItemSize = New Size(44, 136)
    End Sub
    Protected Overrides Sub CreateHandle()
        MyBase.CreateHandle()
        Alignment = TabAlignment.Left
    End Sub

    Function ToPen(ByVal color As Color) As Pen
        Return New Pen(color)
    End Function

    Function ToBrush(ByVal color As Color) As Brush
        Return New SolidBrush(color)
    End Function

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Dim B As New Bitmap(Width, Height)
        Dim G As Graphics = Graphics.FromImage(B)
        Try : SelectedTab.BackColor = Color.White : Catch : End Try
        G.Clear(Color.White)
        G.FillRectangle(New SolidBrush(Color.FromArgb(246, 248, 252)), New Rectangle(0, 0, ItemSize.Height + 4, Height))
        'G.DrawLine(New Pen(Color.FromArgb(170, 187, 204)), New Point(Width - 1, 0), New Point(Width - 1, Height - 1))    'comment out to get rid of the borders
        'G.DrawLine(New Pen(Color.FromArgb(170, 187, 204)), New Point(ItemSize.Height + 1, 0), New Point(Width - 1, 0))                   'comment out to get rid of the borders
        'G.DrawLine(New Pen(Color.FromArgb(170, 187, 204)), New Point(ItemSize.Height + 3, Height - 1), New Point(Width - 1, Height - 1)) 'comment out to get rid of the borders
        G.DrawLine(New Pen(Color.FromArgb(170, 187, 204)), New Point(ItemSize.Height + 3, 0), New Point(ItemSize.Height + 3, 999))
        For i = 0 To TabCount - 1
            If i = SelectedIndex Then
                Dim x2 As Rectangle = New Rectangle(New Point(GetTabRect(i).Location.X - 2, GetTabRect(i).Location.Y - 2), New Size(GetTabRect(i).Width + 3, GetTabRect(i).Height - 1))
                Dim myBlend As New ColorBlend()
                myBlend.Colors = {Color.FromArgb(232, 232, 240), Color.FromArgb(232, 232, 240), Color.FromArgb(232, 232, 240)}
                myBlend.Positions = {0.0F, 0.5F, 1.0F}
                Dim lgBrush As New LinearGradientBrush(x2, Color.Black, Color.Black, 90.0F)
                lgBrush.InterpolationColors = myBlend
                G.FillRectangle(lgBrush, x2)
                G.DrawRectangle(New Pen(Color.FromArgb(170, 187, 204)), x2)


                G.SmoothingMode = SmoothingMode.HighQuality
                Dim p() As Point = {New Point(ItemSize.Height - 3, GetTabRect(i).Location.Y + 20), New Point(ItemSize.Height + 4, GetTabRect(i).Location.Y + 14), New Point(ItemSize.Height + 4, GetTabRect(i).Location.Y + 27)}
                G.FillPolygon(Brushes.White, p)
                G.DrawPolygon(New Pen(Color.FromArgb(170, 187, 204)), p)

                If ImageList IsNot Nothing Then
                    Try
                        If ImageList.Images(TabPages(i).ImageIndex) IsNot Nothing Then

                            G.DrawImage(ImageList.Images(TabPages(i).ImageIndex), New Point(x2.Location.X + 8, x2.Location.Y + 6))
                            G.DrawString("      " & TabPages(i).Text, Font, Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                        Else
                            G.DrawString(TabPages(i).Text, New Font(Font.FontFamily, Font.Size, FontStyle.Bold), Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                        End If
                    Catch ex As Exception
                        G.DrawString(TabPages(i).Text, New Font(Font.FontFamily, Font.Size, FontStyle.Bold), Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                    End Try
                Else
                    G.DrawString(TabPages(i).Text, New Font(Font.FontFamily, Font.Size, FontStyle.Bold), Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                End If

                G.DrawLine(New Pen(Color.FromArgb(200, 200, 250)), New Point(x2.Location.X - 1, x2.Location.Y - 1), New Point(x2.Location.X, x2.Location.Y))
                G.DrawLine(New Pen(Color.FromArgb(200, 200, 250)), New Point(x2.Location.X - 1, x2.Bottom - 1), New Point(x2.Location.X, x2.Bottom))
            Else
                Dim x2 As Rectangle = New Rectangle(New Point(GetTabRect(i).Location.X - 2, GetTabRect(i).Location.Y - 2), New Size(GetTabRect(i).Width + 3, GetTabRect(i).Height + 1))
                G.FillRectangle(New SolidBrush(Color.FromArgb(246, 248, 252)), x2)
                G.DrawLine(New Pen(Color.FromArgb(170, 187, 204)), New Point(x2.Right, x2.Top), New Point(x2.Right, x2.Bottom))
                If ImageList IsNot Nothing Then
                    Try
                        If ImageList.Images(TabPages(i).ImageIndex) IsNot Nothing Then
                            G.DrawImage(ImageList.Images(TabPages(i).ImageIndex), New Point(x2.Location.X + 8, x2.Location.Y + 6))
                            G.DrawString("      " & TabPages(i).Text, Font, Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                        Else
                            G.DrawString(TabPages(i).Text, Font, Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                        End If
                    Catch ex As Exception
                        G.DrawString(TabPages(i).Text, Font, Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                    End Try
                Else
                    G.DrawString(TabPages(i).Text, Font, Brushes.DimGray, x2, New StringFormat With {.LineAlignment = StringAlignment.Center, .Alignment = StringAlignment.Center})
                End If
            End If
        Next

        e.Graphics.DrawImage(B.Clone, 0, 0)
        G.Dispose() : B.Dispose()
    End Sub
End Class
1
répondu Dwayne Reid 2017-08-24 03:15:52

il y a un tutoriel fourni par Microsoft pour le faire avec le TabControl existant sur MSDN, avec un exemple de code donné à la fois en C# et Visual Basic .NET. Leur méthode est basée sur l'utilisation du dessin du propriétaire. Résumant leurs étapes ci-dessous:

  1. définir les Alignement propriété Droit.

  2. assurez-vous que tous les onglets ont la même largeur horizontale en réglant le SizeMode propriété Fixe.

  3. mettez le ItemSize bien à votre taille préférée pour les onglets, en gardant à l'esprit que la largeur et la hauteur sont inversés.

  4. mettez le DrawMode propriété OwnerDrawFixed.

  5. configurer un gestionnaire d'événements pour lesDrawItem événement, et le lieu de votre propriétaire de dessin code n' dictant comment chaque onglet doit être affiché. Leur exemple de code C# pour le gestionnaire d'événements est reproduit ci-dessous pour plus de commodité (il suppose que votre TabControl est nommé tabControl1:

    private void tabControl1_DrawItem(Object sender, System.Windows.Forms.DrawItemEventArgs e)
    {
        Graphics g = e.Graphics;
        Brush _textBrush;
    
        // Get the item from the collection.
        TabPage _tabPage = tabControl1.TabPages[e.Index];
    
        // Get the real bounds for the tab rectangle.
        Rectangle _tabBounds = tabControl1.GetTabRect(e.Index);
    
        if (e.State == DrawItemState.Selected)
        {
    
            // Draw a different background color, and don't paint a focus rectangle.
            _textBrush = new SolidBrush(Color.Red);
            g.FillRectangle(Brushes.Gray, e.Bounds);
        }
        else
        {
            _textBrush = new System.Drawing.SolidBrush(e.ForeColor);
            e.DrawBackground();
        }
    
        // Use our own font.
        Font _tabFont = new Font("Arial", (float)10.0, FontStyle.Bold, GraphicsUnit.Pixel);
    
        // Draw string. Center the text.
        StringFormat _stringFlags = new StringFormat();
        _stringFlags.Alignment = StringAlignment.Center;
        _stringFlags.LineAlignment = StringAlignment.Center;
        g.DrawString(_tabPage.Text, _tabFont, _textBrush, _tabBounds, new StringFormat(_stringFlags));
    }
    

Vous pouvez probablement expérimenter avec votre ItemSize propriété et le _tabFont valeur à partir du code ci-dessus pour affiner l'apparence de vos onglets à tout ce dont vous avez besoin. Pour un style encore plus fantaisiste, je recommande de regarder cet autre article MSDN départ point.

(Source: Comment: afficher des onglets alignés latéralement avec TabControl (MSDN))

0
répondu Christopher Kyle Horton 2017-05-03 17:35:40