Resize form and all controls in proportion to their startup size/location

m_elias

Member
Joined
Jan 3, 2012
Messages
11
Location
Canada
Programming Experience
1-3
I have been searching for a solution to this but I can't find one. I have played with the anchor and dock properties but they are not doing what I want, so here goes...

I would like to place and size all of my controls on my form and then when the form is re-sized during run time (different resolutions, full screen/windowed, etc), have everything just scale up or down accordingly. Anchoring the controls to all four sides of my form re-sizes the control properly but it doesn't move it's location in sync with the other control's size next to it, they begin to overlap each other. Am I going to have to code my own scaling code for each control in my program?
 
Anchor is about relative position, not scale. If you want controls to scale then yes, you will have to write code to do it. The reason that it's not catered for is because it is something that very few people want to do, with good reason.
 
Maybe you should attach a screenshot of your form because it may be that using the TableLayoutPanel and/or FlowLayoutPanel will do what you need. We'd need to understand the layout to know for sure though.
 
My form is a bit of a special design. The first screenshot is how it looks in design/programming mode, and the second is how it looks during runtime. The right tabcontrol is left aligned and it slides into view when it has focus, otherwise it sits there with just the tabs visible. I have the two tabcontrols resizing according to the form's size in the form1_sizechanged() event by manually calculating their new size/position relative to their original starting size/position. I would like to figure something out that allowed me to just place and size future controls and have VB take care of scaling it for me.

design view.PNG

runtime view.PNG
 
Is there a way I can loop through all the form's controls, save their startup size and location into an array and then whenever the form's size changes, loop through all the controls again comparing their original sizes and calculate new sizes and locations?
 
Progress Update

The code below is what I've come up with. Create a new form called form1, throw in some controls (textbox, label, button, etc) and try resizing the form. It appears to work well with controls that are directly on form1, any control that is in a tabcontrol is not detected and not scaled by this technique (the tabcontrol is scaled just not the controls in it's container). Right now it looks like I will have to duplicate this code for each tabpage on both of my tabcontrols. Does anyone have ideas how to automate this? Maybe a hint, everything here is new to me. My mind has been blown enough for one day.

VB.NET:
Public Class Form1
    Public NameControlDesign() As String
    Public LocationControlDesign() As Point
    Public SizeControlDesign() As Size
    Public SizeFormDesign As Size

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        ReDim NameControlDesign(Me.Controls.Count)
        ReDim LocationControlDesign(Me.Controls.Count)
        ReDim SizeControlDesign(Me.Controls.Count)
        SizeFormDesign = Me.Size

        For i As Integer = 0 To Me.Controls.Count - 1
            NameControlDesign(i) = Me.Controls(i).Name
            LocationControlDesign(i) = Me.Controls(i).Location
            SizeControlDesign(i) = Me.Controls(i).Size
        Next i
    End Sub

    Private Sub Form1_SizeChanged(sender As Object, e As System.EventArgs) Handles Me.SizeChanged
        For a As Integer = 0 To sender.Controls.Count - 1
            sender.Controls(a).Location = New  Point(sender.Size.Width / SizeFormDesign.Width *  LocationControlDesign(a).X, sender.Size.Height / SizeFormDesign.Height *  LocationControlDesign(a).Y)
            sender.Controls(a).Size = New Size(sender.Size.Width /  SizeFormDesign.Width * SizeControlDesign(a).Width, sender.Size.Height /  SizeFormDesign.Height * SizeControlDesign(a).Height)
        Next a
    End Sub
 
The revised code for resizing font will be as follows:
Public Class Form1
Public NameControlDesign() As String
Public LocationControlDesign() As Point
Public SizeControlDesign() As Size
Public SizeFormDesign As Size
Public LastSize As Size
Private font_size As Double
Private new_font_size As Double
Public heightratio As Double
Public widthratio As Double
Dim origWidth As Integer
Dim origHeight As Integer

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
LastSize = Me.Size
font_size = Me.Font.Size
new_font_size = Me.Font.Size
origWidth = Me.Width
origHeight = Me.Height
ReDim NameControlDesign(Me.Controls.Count)
ReDim LocationControlDesign(Me.Controls.Count)
ReDim SizeControlDesign(Me.Controls.Count)
SizeFormDesign = Me.Size


For i As Integer = 0 To Me.Controls.Count - 1
NameControlDesign(i) = Me.Controls(i).Name
LocationControlDesign(i) = Me.Controls(i).Location
SizeControlDesign(i) = Me.Controls(i).Size
Next i
End Sub


Private Sub Form1_SizeChanged(sender As Object, e As System.EventArgs) Handles Me.SizeChanged


heightratio = Me.Height / origHeight
widthratio = Me.Width / origWidth
new_font_size = Math.Max(4, Math.Round(font_size * _
IIf(Math.Abs(heightratio) < Math.Abs(widthratio), _
heightratio, widthratio), 0))


For a As Integer = 0 To sender.Controls.Count - 1
sender.Controls(a).Location = New Point(sender.Size.Width / SizeFormDesign.Width * LocationControlDesign(a).X, sender.Size.Height / SizeFormDesign.Height * LocationControlDesign(a).Y)
sender.Controls(a).Size = New Size(sender.Size.Width / SizeFormDesign.Width * SizeControlDesign(a).Width, sender.Size.Height / SizeFormDesign.Height * SizeControlDesign(a).Height)
Next a
Me.Refresh()
End Sub
End Class
From: Sumit Saha
 
As for automating your algorithm for all controls, I hope this will help:

From the post http://www.vbdotnetforums.com/vb-net-general-discussion/46696-list-all-controls.html

This code will apparently give you duplicate controls with the proper names and properties of all controls in your project, through recursive control inspection:

VB.NET:
Private Sub ControlsTree(node As TreeNode, controls As Control.ControlCollection)
For Each ctrl As Control In controls 
If ctrl.Name <> String.Empty Then
Dim child = node.Nodes.Add(ctrl.GetType.Name & ": " & ctrl.Name)            
ControlsTree(child, ctrl.Controls)        
End If    
Next
End Sub

Then looping and adding each form, using reflection on My.Forms collection:

VB.NET:
For Each formprop In My.Forms.GetType.GetProperties
Dim node = Me.FormsTreeView.Nodes.Add(formprop.Name)    
Dim frm As Form = CType(formprop.GetValue(My.Forms, Nothing), Form)    
ControlsTree(node, frm.Controls)
Next

 
Sorry, I missed one line of code for the revised code after
sender.Controls(a).Size = New Size(sender.Size.Width / SizeFormDesign.Width * SizeControlDesign(a).Width, sender.Size.Height / SizeFormDesign.Height * SizeControlDesign(a).Height)
The missing line after the above will be as follows:
sender.controls(a).font = New System.Drawing.Font("Consolas", Int(new_font_size)) 'or whatever name of the Font you are using
From Sumit Saha
 
Back
Top