Click here to Skip to main content
16,021,125 members
Articles / Programming Languages / Visual Basic
Tip/Trick

VB.NET - Dynamically Resize and Reposition All Controls when Form is Resized, Including Font Sizes

Rate me:
Please Sign up or sign in to vote.
4.98/5 (43 votes)
3 Sep 2015CPOL2 min read 248.3K   111   39   70
VB.NET - Resize and Reposition all controls when Form is resized

Introduction

I've seen several VB.NET articles posted here regarding proportionally resizing and repositioning controls on a VB.NET form when the form is resized. I tried some of them with varying levels of success, including Docking and Anchoring controls. None seemed to get me exactly what I needed. I need for controls to reposition and resize without being fixed to any border and without growing and overlaying each other.

Listed below is a solution I came up with implementing the behavior in a small Resizer class that can be included and used in any form easily.

The complete code is listed below. I welcome any thought/ideas for improvements. Also, while this class is written in VB, rewriting in C# would be simple.

Thanks.

Background

The Resizer class has two public methods:

  • FindAllControls(control)
  • ResizeAllControls(control)

The class is used by first calling the FindAllControls method during the Form's Load event. Internally, the class stores the original relative position and size of each control on a form in an internal Dictionary object.

Then, in the Form's Resize event, ResizeAllControls is called to adjust controls proportionally based on their stored original information and the new form size.

The FindAllControls and ResizeAllControls procedures are written to recursively process container controls. There are many examples available online to demonstrate this method of processing container controls.

Font sizes are also modified during resizing. A new font size is calculated using an average of the control's relative height and width change.

Note: Label controls will not resize if their AutoSize property is set to 'True'.

Again, any suggestions for improvement are welcome.

Using the Code

After adding the class file, Resizer.vb, to a VB.NET project, three lines of Form code are needed to use the ReSize class:

  1. Declare a form-level instance of the Resizer class:
    VB.NET
    Dim rs as New Resizer
  2. In the Form_Load event procedure, call the FindAllControls method, passing the form as a parameter:
    VB.NET
    rs.FindAllControls(Me)
  3. In the Form_Resize event procedure, call the ResizeAllControls method, passing the form as a parameter:
    VB.NET
    rs.ResizeAllControls(Me)

A complete Form code example:

VB.NET
Public Class Form1
    Dim rs As New Resizer

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        rs.FindAllControls(Me)

    End Sub

    Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize
        rs.ResizeAllControls(Me)
    End Sub
End Class

The complete class code is as follows:

VB.NET
'-------------------------------------------------------------------------------
' Resizer
' This class is used to dynamically resize and reposition all controls on a form.
' Container controls are processed recursively so that all controls on the form
' are handled.
'
' Usage:
'  Resizing functionality requires only three lines of code on a form:
'
'  1. Create a form-level reference to the Resize class:
'     Dim myResizer as Resizer
'
'  2. In the Form_Load event, call the  Resizer class FIndAllControls method:
'     myResizer.FindAllControls(Me)
'
'  3. In the Form_Resize event, call the  Resizer class ResizeAllControls method:
'     myResizer.ResizeAllControls(Me)
'
'-------------------------------------------------------------------------------
Public Class Resizer

    '----------------------------------------------------------
    ' ControlInfo
    ' Structure of original state of all processed controls
    '----------------------------------------------------------
    Private Structure ControlInfo
        Public name As String
        Public parentName As String
        Public leftOffsetPercent As Double
        Public topOffsetPercent As Double
        Public heightPercent As Double
        Public originalHeight As Integer
        Public originalWidth As Integer
        Public widthPercent As Double
        Public originalFontSize As Single
    End Structure

    '-------------------------------------------------------------------------
    ' ctrlDict
    ' Dictionary of (control name, control info) for all processed controls
    '-------------------------------------------------------------------------
    Private ctrlDict As Dictionary(Of String, ControlInfo) = New Dictionary(Of String, ControlInfo)

    '----------------------------------------------------------------------------------------
    ' FindAllControls
    ' Recursive function to process all controls contained in the initially passed
    ' control container and store it in the Control dictionary
    '----------------------------------------------------------------------------------------
    Public Sub FindAllControls(thisCtrl As Control)

        '-- If the current control has a parent, store all original relative position
        '-- and size information in the dictionary.
        '-- Recursively call FindAllControls for each control contained in the
        '-- current Control
        For Each ctl As Control In thisCtrl.Controls
            Try
                If Not IsNothing(ctl.Parent) Then
                    Dim parentHeight = ctl.Parent.Height
                    Dim parentWidth = ctl.Parent.Width

                    Dim c As New ControlInfo
                    c.name = ctl.Name
                    c.parentName = ctl.Parent.Name
                    c.topOffsetPercent = Convert.ToDouble(ctl.Top) / Convert.ToDouble(parentHeight)
                    c.leftOffsetPercent = Convert.ToDouble(ctl.Left) / Convert.ToDouble(parentWidth)
                    c.heightPercent = Convert.ToDouble(ctl.Height) / Convert.ToDouble(parentHeight)
                    c.widthPercent = Convert.ToDouble(ctl.Width) / Convert.ToDouble(parentWidth)
                    c.originalFontSize = ctl.Font.Size
                    c.originalHeight = ctl.Height
                    c.originalWidth = ctl.Width
                    ctrlDict.Add(c.name, c)
                End If

            Catch ex As Exception
                Debug.Print(ex.Message)
            End Try

            If ctl.Controls.Count > 0 Then
                FindAllControls(ctl)
            End If

        Next '-- For Each

    End Sub

    '----------------------------------------------------------------------------------------
    ' ResizeAllControls
    ' Recursive function to resize and reposition all controls contained in the Control
    ' dictionary
    '----------------------------------------------------------------------------------------
    Public Sub ResizeAllControls(thisCtrl As Control)

        Dim fontRatioW As Single
        Dim fontRatioH As Single
        Dim fontRatio As Single
        Dim f As Font

        '-- Resize and reposition all controls in the passed control
        For Each ctl As Control In thisCtrl.Controls
            Try
                If Not IsNothing(ctl.Parent) Then
                    Dim parentHeight = ctl.Parent.Height
                    Dim parentWidth = ctl.Parent.Width

                    Dim c As New ControlInfo

                    Dim ret As Boolean = False
                    Try
                        '-- Get the current control's info from the control info dictionary
                        ret = ctrlDict.TryGetValue(ctl.Name, c)

                        '-- If found, adjust the current control based on control relative
                        '-- size and position information stored in the dictionary
                        If (ret) Then
                            '-- Size
                            ctl.Width = Int(parentWidth * c.widthPercent)
                            ctl.Height = Int(parentHeight * c.heightPercent)

                            '-- Position
                            ctl.Top = Int(parentHeight * c.topOffsetPercent)
                            ctl.Left = Int(parentWidth * c.leftOffsetPercent)

                            '-- Font
                            f = ctl.Font
                            fontRatioW = ctl.Width / c.originalWidth
                            fontRatioH = ctl.Height / c.originalHeight
                            fontRatio = (fontRatioW + 
                            fontRatioH) / 2 '-- average change in control Height and Width
                            ctl.Font = New Font(f.FontFamily, 
                            c.originalFontSize * fontRatio, f.Style)

                        End If
                    Catch
                    End Try
                End If
            Catch ex As Exception
            End Try

            '-- Recursive call for controls contained in the current control
            If ctl.Controls.Count > 0 Then
                ResizeAllControls(ctl)
            End If

        Next '-- For Each
    End Sub

End Class

Points of Interest

VB.NET - Simple class that dynamically Resizes and Repositions all controls when a Form is resized, including Font sizes with only three lines of code in your form.

History

  • 3rd September, 2015: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
AnswerRe: GyResizer Class quastion Pin
Member 159027422-Oct-23 16:49
Member 159027422-Oct-23 16:49 
QuestionIt work for me Pin
Member 141711799-Mar-20 17:49
Member 141711799-Mar-20 17:49 
SuggestionResizer issue with line and rectangle control Pin
Benny C. A.25-Nov-19 20:11
Benny C. A.25-Nov-19 20:11 
QuestionForm resizer class of Member 10974085 Pin
Member 1356965021-Oct-19 9:16
Member 1356965021-Oct-19 9:16 
PraiseMAGIC! Pin
Member 1026739820-Sep-19 3:24
Member 1026739820-Sep-19 3:24 
Questioncompliments Pin
Member 82166919-Sep-19 10:29
Member 82166919-Sep-19 10:29 
QuestionThanks For The Code It works like Charma Pin
Vyas Darshan3-Aug-19 2:05
Vyas Darshan3-Aug-19 2:05 
GeneralMy vote of 5 Pin
mavmag7-Apr-19 6:51
mavmag7-Apr-19 6:51 
SuggestionAnother Version (to avoid the problems with label autosize) Pin
esnivan@gmail.com3-Sep-18 1:36
esnivan@gmail.com3-Sep-18 1:36 
GeneralRe: Another Version (to avoid the problems with label autosize) Pin
Bartholomew Ho26-Aug-21 20:32
Bartholomew Ho26-Aug-21 20:32 
GeneralRe: Another Version (to avoid the problems with label autosize) Pin
FenderBaba15-Feb-22 4:34
FenderBaba15-Feb-22 4:34 
QuestionGreat but little note need change Pin
Member 1370202328-Feb-18 8:02
Member 1370202328-Feb-18 8:02 
PraiseThanks Pin
Member 1330350327-Jul-17 16:04
Member 1330350327-Jul-17 16:04 
Questionthank you very much Pin
Ta Rek28-Apr-17 22:12
Ta Rek28-Apr-17 22:12 
GeneralMy vote of 3 Pin
عيسى الحرباوي28-Apr-17 8:38
عيسى الحرباوي28-Apr-17 8:38 
QuestionSimply Fantastic! .. DataGridView resize inclusion...? Pin
Member 1312647919-Apr-17 6:40
Member 1312647919-Apr-17 6:40 
AnswerRe: Simply Fantastic! .. DataGridView resize inclusion...? Pin
Member 1304590226-Apr-17 23:49
Member 1304590226-Apr-17 23:49 
GeneralMy vote of 5 Pin
Member 107988831-Apr-17 4:10
Member 107988831-Apr-17 4:10 
Questionexclude control? Pin
Fox24313-Mar-17 15:11
Fox24313-Mar-17 15:11 
QuestionAll controls work fine, except combo-box Pin
Member 1282273815-Nov-16 5:32
Member 1282273815-Nov-16 5:32 
QuestionProblem Pin
Member 1150213929-Jun-16 2:12
Member 1150213929-Jun-16 2:12 
BugThanks for this great code. But ther is one bug. Pin
Centauri_dk7-Apr-16 3:18
Centauri_dk7-Apr-16 3:18 
GeneralRe: Thanks for this great code. But ther is one bug. Pin
Member 109740857-Apr-16 10:35
Member 109740857-Apr-16 10:35 
Questionhow resize image in button Pin
Nicola Gennaro15-Mar-16 1:12
Nicola Gennaro15-Mar-16 1:12 
QuestionExcellent updates davepank and 11584228 Pin
Member 1097408513-Feb-16 2:55
Member 1097408513-Feb-16 2:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.