Bujar Ademi

Bujar Ademi

Windows Programmer

Extended GroupBox

On my current project, the .NET control GroupBox doesn’t fit to my needs, so I decide to make my own control that will have nice look with some features that I can use in the future.

First hit was to make a custom control from Panels, but I saw that inheriting GroupBox with be much easier and perfect way to create control that I needed.

Extended control from GroupBox contain two additional methods that are used on OnPaint method of the GroupBox control.

 

Private Function GetRoundedRectanglarPath(ByVal aoRectangle As Rectangle, ByVal aoSize As Size) As GraphicsPath Dim oExteriorGraphicPath As New GraphicsPath() oExteriorGraphicPath.AddLine(aoRectangle.Left, aoRectangle.Top, aoRectangle.Right, aoRectangle.Top) oExteriorGraphicPath.AddLine(aoRectangle.Right, aoRectangle.Top + aoSize.Height, aoRectangle.Right, aoRectangle.Bottom - CType(aoSize.Height / 2, Single)) oExteriorGraphicPath.AddLine(aoRectangle.Right, aoRectangle.Bottom, aoRectangle.Left, aoRectangle.Bottom) oExteriorGraphicPath.AddLine(aoRectangle.Left, aoRectangle.Bottom, aoRectangle.Left, aoRectangle.Top) Return oExteriorGraphicPath End Function

 

This function is used to get Rectangular GraphicsPath.
Okay, I am stupid on commenting things, probably I never used to comment my own code, so I will post whole class, if you have something unclear feel free to comment or write me on email.

Imports System
Imports System.ComponentModel
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Runtime.CompilerServices
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Public Class MyGroupBox
Inherits GroupBox

#Region "Fields"
' Defining the data member corresponding to different Properties and initializing default values
Private _BorderColor As Color = Color.FromKnownColor(KnownColor.ControlDark)
Private _TitleColor As Color = Color.FromKnownColor(KnownColor.ControlDark)
Private _BorderColorGradient As Color = Color.FromKnownColor(KnownColor.Gainsboro)
Private _TitleFont As Font
Private _ColorAngle As Single = 30.0F
Private moHeadingTextColor As Color = Color.WhiteSmoke ' HeaderTextColor Property
Protected mosizeBorderPixelIndent As Size ' Size of the radius of the curves at the corners
Protected moTextSize As SizeF ' Size(In Floating Point) of the text in pixels based on the font
#End Region
#Region "Property"
' This property defines the border within which the whole control is to be drawn.
Protected ReadOnly Property BorderRectangle() As Rectangle
Get
Dim rc As Rectangle = Me.ClientRectangle ' We reduce the size of drawing to show everything properly.
Return New Rectangle(0, 0, rc.Width - 3, rc.Height - 3)
End Get
End Property
Public Property FontColor() As Color
Get
Return moHeadingTextColor
End Get
Set(ByVal value As Color)
moHeadingTextColor = value
Me.Invalidate()
End Set
End Property
Public Property TitleFont() As Font
Get
Return Me._TitleFont
End Get
Set(ByVal value As Font)
Me._TitleFont = value
Me.Invalidate()
End Set
End Property
Public Property BorderColor() As Color
Get
Return Me._BorderColor
End Get
Set(ByVal value As Color)
Me._BorderColor = value
Me.Invalidate()
End Set
End Property
Public Property TitleColor() As Color
Get
Return Me._TitleColor
End Get
Set(ByVal value As Color)
Me._TitleColor = value
Me.Invalidate()
End Set
End Property
Public Property ColorAngle() As Single
Get
Return Me._ColorAngle
End Get
Set(ByVal value As Single)
Me._ColorAngle = value
Me.Invalidate()
End Set
End Property
Public Property BorderColorGradient() As Color
Get
Return Me._BorderColorGradient
End Get
Set(ByVal value As Color)
Me._BorderColorGradient = value
Me.Invalidate()
End Set
End Property
#End Region

#Region "Overridable Properties"
Protected Overridable ReadOnly Property ExteriorRegionPath() As GraphicsPath
Get
Dim oRectangle As New Rectangle(Me.BorderRectangle.X, Me.BorderRectangle.Y, Me.BorderRectangle.Width + 1, Me.BorderRectangle.Height + 1)
Dim oSize As New Size(mosizeBorderPixelIndent.Width + 2, mosizeBorderPixelIndent.Height + 2)
Return Me.GetRoundedRectanglarPath(oRectangle, oSize)
End Get
End Property
#End Region

Public Sub New()
MyBase.New()
Me.SetStyle(System.Windows.Forms.ControlStyles.UserPaint Or System.Windows.Forms.ControlStyles.AllPaintingInWmPaint Or System.Windows.Forms.ControlStyles.DoubleBuffer, True)
mosizeBorderPixelIndent = New Size(16, 16)
Me._TitleFont = New Font("Tahoma", 10.0!, FontStyle.Bold)
End Sub
#Region "Overridable Methods"
Protected Overridable Sub DrawBorder(ByVal aoGraphics As Graphics, ByVal aoRectangle As Rectangle)
Dim oPen As Pen
Dim oSize As New Size(mosizeBorderPixelIndent.Width, mosizeBorderPixelIndent.Height)
Dim oRectangle As New Rectangle(aoRectangle.X, aoRectangle.Y, aoRectangle.Width, aoRectangle.Height)
Dim szText As SizeF = aoGraphics.MeasureString(Me.Text, Me.Font)

oPen = New Pen(Me._BorderColor)
aoGraphics.DrawLine(oPen, aoRectangle.Left, aoRectangle.Top, aoRectangle.Right, aoRectangle.Top)
aoGraphics.DrawLine(oPen, oRectangle.Right, oRectangle.Top, oRectangle.Right, oRectangle.Bottom)
aoGraphics.DrawLine(oPen, oRectangle.Right, oRectangle.Bottom, oRectangle.Left, oRectangle.Bottom)
aoGraphics.DrawLine(oPen, aoRectangle.Left, aoRectangle.Bottom, aoRectangle.Left, aoRectangle.Top)
End Sub
#End Region
#Region "Private methods"
' This function is used to get Rectangular GraphicsPath
Private Function GetRoundedRectanglarPath(ByVal aoRectangle As Rectangle, ByVal aoSize As Size) As GraphicsPath
Dim oExteriorGraphicPath As New GraphicsPath()
oExteriorGraphicPath.AddLine(aoRectangle.Left, aoRectangle.Top, aoRectangle.Right, aoRectangle.Top)
oExteriorGraphicPath.AddLine(aoRectangle.Right, aoRectangle.Top + aoSize.Height, aoRectangle.Right, aoRectangle.Bottom - CType(aoSize.Height / 2, Single))
oExteriorGraphicPath.AddLine(aoRectangle.Right, aoRectangle.Bottom, aoRectangle.Left, aoRectangle.Bottom)
oExteriorGraphicPath.AddLine(aoRectangle.Left, aoRectangle.Bottom, aoRectangle.Left, aoRectangle.Top)
Return oExteriorGraphicPath
End Function
#End Region

#Region "Overriden Events"
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
' Get the size of the string in pixels for the string for a font
Me.moTextSize = e.Graphics.MeasureString(Me.Text, Me.TitleFont)

' Original Smoothing is Saved and Smoothing mode mode is change to AntiAlias
Dim oldSmooting As SmoothingMode = e.Graphics.SmoothingMode
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias

' Draws border for the control
DrawBorder(e.Graphics, Me.BorderRectangle)
' Defines string format to center the string
Dim oStringFormat As New StringFormat()
Dim oRect As New Rectangle(Me.BorderRectangle.X - 0.5, Me.BorderRectangle.Y + 0.5, Me.BorderRectangle.Width - 0.5, moTextSize.Height + 6)
Dim LinearFill As LinearGradientBrush = New LinearGradientBrush(oRect, Me._TitleColor, Me._BorderColorGradient, Me._ColorAngle)
e.Graphics.FillRectangle(LinearFill, oRect)

Dim oRectangleF As New RectangleF(Me.BorderRectangle.X + CType(Me.mosizeBorderPixelIndent.Width / 2, Single) + 8, Me.BorderRectangle.Y + 3, moTextSize.Width + CType(Me.mosizeBorderPixelIndent.Width / 2, Single), moTextSize.Height + 1)

e.Graphics.DrawString(Me.Text, Me.TitleFont, New SolidBrush(moHeadingTextColor), oRectangleF, oStringFormat)

e.Graphics.SmoothingMode = oldSmooting
Me.Region = New Region(Me.ExteriorRegionPath)
End Sub
#End Region
End Class