Click here to Skip to main content
15,881,852 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 233.9K   109   39   64
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

 
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 
QuestionSpeed increase #2 Pin
davepank12-Feb-16 17:02
davepank12-Feb-16 17:02 
QuestionSpeed increase.. Pin
davepank12-Feb-16 16:45
davepank12-Feb-16 16:45 
QuestionA suggestion. Pin
José Manuel Surroca10-Feb-16 23:59
José Manuel Surroca10-Feb-16 23:59 
PraiseI found exactly was lookin for!! Pin
rom32316-Jan-16 13:23
rom32316-Jan-16 13:23 
GeneralRe: I found exactly was lookin for!! Pin
Member 1097408513-Feb-16 4:45
Member 1097408513-Feb-16 4:45 
QuestionNice work but menu bar get sqizzed Pin
SumitSaha7-Jan-16 11:08
SumitSaha7-Jan-16 11:08 
Can you please look into the matter and modify the code to correct the situation so that the menu bar appears properly.
AnswerRe: Nice work but menu bar get sqizzed Pin
Member 1097408513-Feb-16 4:43
Member 1097408513-Feb-16 4:43 
AnswerRe: Nice work but menu bar get sqizzed Pin
SumitSaha2-Mar-16 7:54
SumitSaha2-Mar-16 7:54 
QuestionCode snippet Pin
TheModuleFactory19-Dec-15 11:03
professionalTheModuleFactory19-Dec-15 11:03 
AnswerRe: Code snippet Pin
Member 1097408519-Dec-15 11:10
Member 1097408519-Dec-15 11:10 
QuestionVery Good but one adjustment Pin
MGM de Wit9-Sep-15 21:58
MGM de Wit9-Sep-15 21:58 
AnswerRe: Very Good but one adjustment Pin
Member 1097408510-Sep-15 10:22
Member 1097408510-Sep-15 10:22 
AnswerRe: Very Good but one adjustment Pin
Member 1198129624-Mar-17 16:09
Member 1198129624-Mar-17 16:09 
GeneralRe: Very Good but one adjustment Pin
MGM de Wit26-Mar-17 23:31
MGM de Wit26-Mar-17 23:31 
QuestionNice Pin
jecarts8-Sep-15 7:33
jecarts8-Sep-15 7:33 
SuggestionExcellent! Here are the semicolons and curley brackets at no extra charge ;) Pin
Bruce Greene6-Sep-15 7:11
Bruce Greene6-Sep-15 7:11 
GeneralRe: Excellent! Here are the semicolons and curley brackets at no extra charge ;) Pin
ninodago11-Sep-15 2:59
ninodago11-Sep-15 2:59 
GeneralMy vote of 5 Pin
dmjm-h4-Sep-15 11:39
dmjm-h4-Sep-15 11:39 
GeneralVery nice and very simple in its layout Pin
ninodago4-Sep-15 10:00
ninodago4-Sep-15 10:00 
QuestionNice work Pin
Dharmesh .S. Patil3-Sep-15 19:32
professionalDharmesh .S. Patil3-Sep-15 19:32 

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.