Click here to Skip to main content
14,691,021 members
Articles » Languages » VB.NET » Windows Forms
Tip/Trick
Posted 3 Sep 2015

Stats

146.3K views
38 bookmarked

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 (39 votes)
3 Sep 2015CPOL
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:
    Dim rs as New Resizer
  2. In the Form_Load event procedure, call the FindAllControls method, passing the form as a parameter:
    rs.FindAllControls(Me)
  3. In the Form_Resize event procedure, call the ResizeAllControls method, passing the form as a parameter:
    rs.ResizeAllControls(Me)

A complete Form code example:

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:

'-------------------------------------------------------------------------------
' 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)

Share

About the Author

Member 10974085
United States United States
No Biography provided

Comments and Discussions

 
Questionsystem.ArgumentException in mscorlib.dll Pin
Member 1433303623-Sep-20 5:09
MemberMember 1433303623-Sep-20 5:09 
QuestionUpdating this code - ideas Pin
Member 1097408515-Jul-20 3:46
MemberMember 1097408515-Jul-20 3:46 
QuestionRunning from Citrix - not getting parent size properly Pin
Member 1422839730-Apr-20 4:07
MemberMember 1422839730-Apr-20 4:07 
QuestionTab Control Pin
Member 833055429-Apr-20 7:11
MemberMember 833055429-Apr-20 7:11 
QuestionActually, i'm working in Vc++ so please convert code into Vc++ Pin
Member 1477910714-Apr-20 2:52
MemberMember 1477910714-Apr-20 2:52 
QuestionProblem On Dock-able Control Pin
GenSmarty26-Mar-20 5:58
MemberGenSmarty26-Mar-20 5:58 
QuestionGyResizer Class quastion Pin
Member 1356965018-Mar-20 4:31
MemberMember 1356965018-Mar-20 4:31 
QuestionIt work for me Pin
Member 141711799-Mar-20 18:49
MemberMember 141711799-Mar-20 18:49 
SuggestionResizer issue with line and rectangle control Pin
Benny C. A.25-Nov-19 21:11
MemberBenny C. A.25-Nov-19 21:11 
QuestionForm resizer class of Member 10974085 Pin
Member 1356965021-Oct-19 10:16
MemberMember 1356965021-Oct-19 10:16 
PraiseMAGIC! Pin
Member 1026739820-Sep-19 4:24
MemberMember 1026739820-Sep-19 4:24 
Questioncompliments Pin
Member 82166919-Sep-19 11:29
MemberMember 82166919-Sep-19 11:29 
QuestionThanks For The Code It works like Charma Pin
Vyas Darshan3-Aug-19 3:05
MemberVyas Darshan3-Aug-19 3:05 
GeneralMy vote of 5 Pin
mavmag7-Apr-19 7:51
Membermavmag7-Apr-19 7:51 
SuggestionAnother Version (to avoid the problems with label autosize) Pin
esnivan@gmail.com3-Sep-18 2:36
Memberesnivan@gmail.com3-Sep-18 2:36 
QuestionGreat but little note need change Pin
Member 1370202328-Feb-18 9:02
MemberMember 1370202328-Feb-18 9:02 
PraiseThanks Pin
Member 1330350327-Jul-17 17:04
MemberMember 1330350327-Jul-17 17:04 
Questionthank you very much Pin
Ta Rek28-Apr-17 23:12
MemberTa Rek28-Apr-17 23:12 
GeneralMy vote of 3 Pin
عيسى الحرباوي28-Apr-17 9:38
Memberعيسى الحرباوي28-Apr-17 9:38 
QuestionSimply Fantastic! .. DataGridView resize inclusion...? Pin
Member 1312647919-Apr-17 7:40
MemberMember 1312647919-Apr-17 7:40 
AnswerRe: Simply Fantastic! .. DataGridView resize inclusion...? Pin
Member 1304590227-Apr-17 0:49
MemberMember 1304590227-Apr-17 0:49 
GeneralMy vote of 5 Pin
Member 107988831-Apr-17 5:10
MemberMember 107988831-Apr-17 5:10 
Questionexclude control? Pin
Fox24313-Mar-17 16:11
MemberFox24313-Mar-17 16:11 
QuestionAll controls work fine, except combo-box Pin
Member 1282273815-Nov-16 6:32
MemberMember 1282273815-Nov-16 6:32 
QuestionProblem Pin
Member 1150213929-Jun-16 3:12
MemberMember 1150213929-Jun-16 3:12 

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.