Click here to Skip to main content
16,017,944 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 247.9K   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

 
QuestionGreat Idea Pin
Jeff Law25-Sep-24 21:40
Jeff Law25-Sep-24 21:40 
QuestionResizing code - upon opening Form2 by adding to a panel within Form1 - does not work Pin
Tov Programming tovrent2-Jun-24 7:32
Tov Programming tovrent2-Jun-24 7:32 
AnswerRe: Resizing code - upon opening Form2 by adding to a panel within Form1 - does not work Pin
Member 109740853-Jun-24 2:41
Member 109740853-Jun-24 2:41 
Hmmm. I have note tried the code with Forms loaded into Panels. I would have to look at that use-case.
QuestionError on minimize Pin
Member 99923341-May-24 1:25
Member 99923341-May-24 1:25 
QuestionImprovement required Pin
prakash.handsome21-Mar-24 22:27
prakash.handsome21-Mar-24 22:27 
AnswerRe: Improvement required Pin
Jeff Law26-Sep-24 16:18
Jeff Law26-Sep-24 16:18 
QuestionResize chart in vb Pin
Member 1603590119-Jan-24 23:16
Member 1603590119-Jan-24 23:16 
QuestionAutoResize chart in vb Pin
Member 1603590119-Jan-24 23:11
Member 1603590119-Jan-24 23:11 
QuestionResized controls are too big Pin
Pekovuk21-Oct-23 20:07
Pekovuk21-Oct-23 20:07 
GeneralMy vote of 5 Pin
wizzywig14-Dec-22 20:19
professionalwizzywig14-Dec-22 20:19 
QuestionFound at Last Pin
Member 924683924-Jul-22 6:01
Member 924683924-Jul-22 6:01 
QuestionThank You for sharing this Pin
FenderBaba15-Feb-22 4:24
FenderBaba15-Feb-22 4:24 
Questionthanx Pin
mosab mmt13-Dec-21 11:43
mosab mmt13-Dec-21 11:43 
QuestionReset? Pin
Mugsys RapSheet25-Oct-21 7:42
Mugsys RapSheet25-Oct-21 7:42 
QuestionAny way to EXEMPT a sub-form? Pin
Mugsys RapSheet25-Oct-21 3:59
Mugsys RapSheet25-Oct-21 3:59 
Questionsystem.ArgumentException in mscorlib.dll Pin
Member 1433303623-Sep-20 4:09
Member 1433303623-Sep-20 4:09 
AnswerRe: system.ArgumentException in mscorlib.dll Pin
FenderBaba15-Feb-22 4:40
FenderBaba15-Feb-22 4:40 
QuestionUpdating this code - ideas Pin
Member 1097408515-Jul-20 2:46
Member 1097408515-Jul-20 2:46 
QuestionRunning from Citrix - not getting parent size properly Pin
Member 1422839730-Apr-20 3:07
Member 1422839730-Apr-20 3:07 
QuestionTab Control Pin
Gary_Corbell29-Apr-20 6:11
Gary_Corbell29-Apr-20 6:11 
QuestionRe: Tab Control Pin
Member 150151837-Dec-20 22:46
Member 150151837-Dec-20 22:46 
AnswerRe: Tab Control Pin
Jeff Law26-Sep-24 16:21
Jeff Law26-Sep-24 16:21 
QuestionActually, i'm working in Vc++ so please convert code into Vc++ Pin
Member 1477910714-Apr-20 1:52
Member 1477910714-Apr-20 1:52 
QuestionProblem On Dock-able Control Pin
GenSmarty26-Mar-20 4:58
GenSmarty26-Mar-20 4:58 
QuestionGyResizer Class quastion Pin
Member 1356965018-Mar-20 3:31
Member 1356965018-Mar-20 3:31 

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.