How to Create a Custom VB Button Control in 10 MinutesCreating a custom button control in Visual Basic (VB.NET) lets you tailor appearance and behavior to match your application’s needs. This guide walks through building a reusable, designer-friendly custom button with rounded corners, hover effects, and customizable properties — all in about 10 minutes.
What you’ll build
A Button control that:
- Has rounded corners and custom border
- Changes background and foreground on hover and press
- Exposes properties for corner radius, border color/width, and hover/pressed colors
- Works in the designer and at runtime
Requirements: Visual Studio (2015 or newer) and a VB.NET Windows Forms project.
Step 1 — Create the control class
- In your Windows Forms project, add a new item: Class. Name it CustomButton.vb.
- Replace its contents with a class that inherits from Button and sets styles for custom painting.
Example:
Imports System.ComponentModel Imports System.Drawing.Drawing2D Imports System.Windows.Forms Public Class CustomButton Inherits Button Private _borderColor As Color = Color.Black Private _borderSize As Integer = 1 Private _radius As Integer = 16 Private _hoverBackColor As Color = Color.LightGray Private _pressedBackColor As Color = Color.Gray Private _defaultBackColor As Color Private _isHover As Boolean = False Private _isPressed As Boolean = False Public Sub New() MyBase.New() SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.OptimizedDoubleBuffer Or ControlStyles.ResizeRedraw, True) FlatStyle = FlatStyle.Flat FlatAppearance.BorderSize = 0 _defaultBackColor = BackColor End Sub <Category("Appearance")> Public Property BorderColor As Color Get Return _borderColor End Get Set(value As Color) _borderColor = value Invalidate() End Set End Property <Category("Appearance")> Public Property BorderSize As Integer Get Return _borderSize End Get Set(value As Integer) _borderSize = Math.Max(0, value) Invalidate() End Set End Property <Category("Appearance")> Public Property Radius As Integer Get Return _radius End Get Set(value As Integer) _radius = Math.Max(0, value) Invalidate() End Set End Property <Category("Appearance")> Public Property HoverBackColor As Color Get Return _hoverBackColor End Get Set(value As Color) _hoverBackColor = value Invalidate() End Set End Property <Category("Appearance")> Public Property PressedBackColor As Color Get Return _pressedBackColor End Get Set(value As Color) _pressedBackColor = value Invalidate() End Set End Property Protected Overrides Sub OnMouseEnter(e As EventArgs) MyBase.OnMouseEnter(e) _isHover = True Invalidate() End Sub Protected Overrides Sub OnMouseLeave(e As EventArgs) MyBase.OnMouseLeave(e) _isHover = False _isPressed = False Invalidate() End Sub Protected Overrides Sub OnMouseDown(mevent As MouseEventArgs) MyBase.OnMouseDown(mevent) If mevent.Button = MouseButtons.Left Then _isPressed = True Invalidate() End If End Sub Protected Overrides Sub OnMouseUp(mevent As MouseEventArgs) MyBase.OnMouseUp(mevent) If mevent.Button = MouseButtons.Left Then _isPressed = False Invalidate() End If End Sub Private Function GetBackColorState() As Color If _isPressed Then Return If(_pressedBackColor = Color.Empty, _defaultBackColor, _pressedBackColor) End If If _isHover Then Return If(_hoverBackColor = Color.Empty, _defaultBackColor, _hoverBackColor) End If Return _defaultBackColor End Function Protected Overrides Sub OnPaint(pevent As PaintEventArgs) MyBase.OnPaint(pevent) Dim g = pevent.Graphics g.SmoothingMode = SmoothingMode.AntiAlias Dim rect = ClientRectangle rect.Inflate(-_borderSize, -_borderSize) Using path = GetRoundedRectanglePath(rect, _radius) Using brush As New SolidBrush(GetBackColorState()) g.FillPath(brush, path) End Using If _borderSize > 0 Then Using pen As New Pen(_borderColor, _borderSize) g.DrawPath(pen, path) End Using End If End Using ' Draw text centered Using sf As New StringFormat() sf.Alignment = StringAlignment.Center sf.LineAlignment = StringAlignment.Center Using foreBrush As New SolidBrush(ForeColor) g.DrawString(Text, Font, foreBrush, ClientRectangle, sf) End Using End Using End Sub Private Function GetRoundedRectanglePath(r As Rectangle, radius As Integer) As GraphicsPath Dim path As New GraphicsPath() Dim d = radius * 2 If radius <= 0 Then path.AddRectangle(r) path.CloseFigure() Return path End If path.AddArc(r.X, r.Y, d, d, 180, 90) path.AddArc(r.Right - d, r.Y, d, d, 270, 90) path.AddArc(r.Right - d, r.Bottom - d, d, d, 0, 90) path.AddArc(r.X, r.Bottom - d, d, d, 90, 90) path.CloseFigure() Return path End Function End Class
Step 2 — Build and add to Toolbox
- Build the project (Build → Build Solution).
- Open the Toolbox, right-click, choose “Choose Items…” and select your compiled assembly or let Visual Studio auto-pick the control. The CustomButton will appear — drag it to a form.
Step 3 — Set properties in Designer
- Corner radius: Radius property (e.g., 12–20 for noticeable rounding).
- BorderColor and BorderSize for outlines.
- HoverBackColor and PressedBackColor for feedback.
- Text, Font, ForeColor as usual.
Step 4 — Optional enhancements (quick ideas)
- Add image support (Image property + alignment).
- Add animations (use a Timer to smoothly interpolate colors).
- Support for theme-aware colors (use SystemColors or app theme).
- Expose shadow or glow via drop shadow drawing.
- Implement IButtonControl to better integrate with Accept/Cancel behavior.
Troubleshooting tips
- If text looks clipped, increase Padding or reduce BorderSize/Radius.
- For flicker-free painting ensure DoubleBuffered is enabled (ControlStyles used above).
- Designer not showing updated properties? Rebuild the project.
Summary
You now have a designer-ready custom VB.NET button with rounded corners, hover/press visuals, and customizable appearance. Paste the class, build, add to Toolbox, and tweak properties — all achievable in roughly 10 minutes.
Leave a Reply