.netvb.netwinformsgraphicsgroupbox

Custom GroupBox Control with colored border


I have found this Custom Control, derived from GroupBox, that allows to change the color of its border.
I understand that the code originally came from StackOverflow, although I cannot find it.

For some reason, when setting the Text Property of the GroupBox, the last letter is always cut out.
Can anyone with more experience than me see anything in the code which is causing this?

Public Class myGroupBox
    Inherits GroupBox

    Private borderColor As Color

    Public Sub New()
        MyBase.New
        Me.borderColor = Color.Blue
    End Sub

    Public Property BorderColour() As Color
        Get
            Return Me.borderColor
        End Get
        Set(ByVal value As Color)
            Me.borderColor = value
        End Set
    End Property

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Dim tSize As Size = TextRenderer.MeasureText(Me.Text, Me.Font)
        Dim borderRect As Rectangle = e.ClipRectangle
        borderRect.Y = (borderRect.Y + (tSize.Height / 2))
        borderRect.Height = (borderRect.Height - (tSize.Height / 2))
        ControlPaint.DrawBorder(e.Graphics, borderRect, Me.borderColor, ButtonBorderStyle.Solid)
        Dim textRect As Rectangle = e.ClipRectangle
        textRect.X = (textRect.X + 6)
        textRect.Width = tSize.Width
        textRect.Height = tSize.Height
        e.Graphics.FillRectangle(New SolidBrush(Me.BackColor), textRect)
        e.Graphics.DrawString(Me.Text, Me.Font, New SolidBrush(Me.ForeColor), textRect)
    End Sub
End Class

Solution

  • There are some problems with that code:

    ► To note: this is not how the Framework draws the borders of a GroupBox. We should draw lines instead, otherwise the text cannot be rendered transparent: since it's the drawn text that hides the line drawn by ControlPaint.DrawBorder, the text background cannot be transparent.

    Here's a revisited version of that Control, with some adjustments that may be useful in other occasions:
    If you think that the Text is drawn too close to the left side, just offset it as required. You could also add a Property to defined the alignment.


    Public Class myGroupBox
        Inherits GroupBox
    
        Private ReadOnly flags As TextFormatFlags =
            TextFormatFlags.Top Or TextFormatFlags.Left Or
            TextFormatFlags.LeftAndRightPadding Or TextFormatFlags.EndEllipsis
        Private m_BorderColor As Color = SystemColors.Window
    
        Public Property BorderColor As Color
            Get
                Return m_BorderColor
            End Get
            Set
                m_BorderColor = Value
                Me.Invalidate()
                If DesignMode Then Me.Parent?.Invalidate(Me.Bounds)
            End Set
        End Property
    
        Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
            Dim midText = TextRenderer.MeasureText(e.Graphics, Text, Font, ClientSize).Height \ 2 + 2
            Dim rect = New Rectangle(0, midText, ClientSize.Width, ClientSize.Height - midText)
            ControlPaint.DrawBorder(e.Graphics, rect, BorderColor, ButtonBorderStyle.Solid)
    
            Dim textRect = Rectangle.Inflate(ClientRectangle, -4, 0)
            TextRenderer.DrawText(e.Graphics, $" {Me.Text} ", Font, textRect, ForeColor, BackColor, flags)
        End Sub
    End Class