[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Resizing objects on a forms maximize

Posted on 2007-07-24
10
Medium Priority
?
424 Views
Last Modified: 2008-01-09
Hi all,

I have a windows form which acts as a menu system. It has three sets of 7 buttons. These 7 buttons are positioned vertically down a form in 3 rows. What I would like is that if the user hits the maximise icon and maximises the form, I want all of the buttons to grow in proportion to the size change. I've looked at anchoring and docking but my form always comes out as a mess! Any ideas guys?

I'm using vs 2004.
0
Comment
Question by:FMabey
  • 3
  • 3
  • 3
  • +1
10 Comments
 
LVL 5

Expert Comment

by:kvimal
ID: 19554948
Set the button size proportion to the size of the Form height and width.
0
 
LVL 7

Expert Comment

by:icr
ID: 19554977
If you are using .NET 2.0 use a TableLayoutPanel
0
 
LVL 3

Author Comment

by:FMabey
ID: 19554998
Unfortunately I'm not using .NET 2.0.
Kvimal, can you explain a little further? Maybe with an example?
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 86

Accepted Solution

by:
Mike Tomlinson earned 500 total points
ID: 19557953
Assuming your form is laid out this way:

B1   B2   B3   B4   B5   B6   B7
B8   B9   B10 B11 B12 B13 B14
B15 B16 B17 B18 B19 B20 B21

...and the buttons should take up the whole form:

Public Class Form1

    Private Sub Form1_Resize(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Resize
        If Me.WindowState <> FormWindowState.Minimized Then
            PositionButtons()
        End If
    End Sub

    Private Sub PositionButtons()
        Dim margin As Integer = 12
        Dim padding As Integer = 6
        Dim btnWidth As Integer = (Me.ClientRectangle.Width - (margin * 2) - (padding * 6)) / 7
        Dim btnHeight As Integer = (Me.ClientRectangle.Height - (margin * 2) - (padding * 2)) / 3
        Dim ctl As Control
        Dim row, col As Integer
        For i As Integer = 1 To 21
            row = (i - 1) \ 7
            col = (i - 1) Mod 7
            ctl = GetControlByName("Button" & i, Me)
            If (Not (ctl Is Nothing)) AndAlso (TypeOf ctl Is Button) Then
                Dim btn As Button = DirectCast(ctl, Button)
                btn.Size = New Size(btnWidth, btnHeight)
                btn.Location = New Point(margin + (col * btnWidth) + (col * padding), margin + (row * btnHeight) + (row * padding))
            End If
        Next
    End Sub

    Private Function GetControlByName(ByVal ctlName As String, ByVal container As Control) As Control
        ctlName = ctlName.ToLower
        For Each c As Control In container.Controls
            If c.Name.ToLower = ctlName Then
                Return c
            ElseIf c.HasChildren Then
                Dim ctl As Control = GetControlByName(ctlName, c)
                If Not (ctl Is Nothing) Then
                    Return ctl
                End If
            End If
        Next
        Return Nothing
    End Function

End Class
0
 
LVL 7

Expert Comment

by:icr
ID: 19560845
An alternative to "finding" the controls is to create the controls in code and storing them in an array. This means you don't have random buttons in the designer where changes in layout don't actually mean anything, and changes can be applied in bulk to the buttons. However, individual changes may be more difficult if you aren't familiar with adding events etc. and you have no visual designer to help you.

Public Class Form1
    Const xButtonCount As Integer = 7
    Const yButtonCount As Integer = 3
    Const buttonMargin As Integer = 12
    Const buttonPadding As Integer = 6

    Dim Buttons(Width, Height) As Button

    Public Sub New()
        Dim x, y As Integer
        Me.SuspendLayout()
        For x = 0 To xButtonCount - 1
            For y = 0 To yButtonCount - 1
                ' NOTE: The resize event will get called after this, so we can leave the
                '       sizing and position to the resize event.
                Buttons(x, y) = New Button()
                Me.Controls.Add(Buttons(x, y))
            Next
        Next
        Me.ResumeLayout()
        Me.InitializeComponent()
    End Sub

    Private Sub Form1_ClientSizeChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.ClientSizeChanged
        If Me.WindowState = FormWindowState.Minimized Then
            Return
        End If

        Dim x, y As Integer
        Dim buttonSize As Size = New Size((Me.ClientRectangle.Width - (buttonMargin * 2) - (buttonPadding * (xButtonCount - 1))) / xButtonCount, (Me.ClientRectangle.Height - (buttonMargin * 2) - (buttonPadding * (yButtonCount - 1))) / yButtonCount)
        Me.SuspendLayout()
        For x = 0 To xButtonCount - 1
            For y = 0 To yButtonCount - 1
                Buttons(x, y).Size = buttonSize
                Buttons(x, y).Location = New Point(buttonMargin + (x * buttonSize.Width) + (x * buttonPadding), buttonMargin + (y * buttonSize.Height) + (y * buttonPadding))
            Next
        Next
        Me.ResumeLayout()
    End Sub
End Class

Even if you do choose to go Idle_Mind's route (which has it's own benefits) I would suggest you only do the lookup at the beginning and then use the array references after that. It will make the code slightly more performant (and as resize is called often it can help):

Public Class Form1
    Const colButtonCount As Integer = 7
    Const rowButtonCount As Integer = 3
    Const buttonMargin As Integer = 12
    Const buttonPadding As Integer = 6

    Dim Buttons(Width, Height) As Button

    Public Sub New()
        InitializeComponent()
        Dim ctl As Control
        For row As Integer = 0 To rowButtonCount - 1
            For col As Integer = 0 To colButtonCount - 1
                ctl = GetControlByName("button" & ((row * colButtonCount) + col + 1), Me)
                If (Not (ctl Is Nothing)) AndAlso (TypeOf ctl Is Button) Then
                    Buttons(col, row) = ctl
                End If
            Next
        Next
        ' Becuse we have already called InitializeComponent to add the controls so we can find them
        ' the ClientSizeChanged event has already been called. Because of this we need to manualy recall it
        ' ourselves to start with the correct layout.
        Form1_ClientSizeChanged(Me, EventArgs.Empty)
    End Sub

    Private Sub Form1_ClientSizeChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.ClientSizeChanged
        If Me.WindowState = FormWindowState.Minimized Then
            Return
        End If

        Dim x, y As Integer
        Dim buttonSize As Size = New Size((Me.ClientRectangle.Width - (buttonMargin * 2) - (buttonPadding * (colButtonCount - 1))) / colButtonCount, (Me.ClientRectangle.Height - (buttonMargin * 2) - (buttonPadding * (rowButtonCount - 1))) / rowButtonCount)
        Me.SuspendLayout()
        For x = 0 To colButtonCount - 1
            For y = 0 To rowButtonCount - 1
                If Not Buttons(x, y) Is Nothing Then
                    Buttons(x, y).Size = buttonSize
                    Buttons(x, y).Location = New Point(buttonMargin + (x * buttonSize.Width) + (x * buttonPadding), buttonMargin + (y * buttonSize.Height) + (y * buttonPadding))
                End If
            Next
        Next
        Me.ResumeLayout()
    End Sub

    Private Function GetControlByName(ByVal ctlName As String, ByVal container As Control) As Control
        ctlName = ctlName.ToLower
        For Each c As Control In container.Controls
            If c.Name.ToLower = ctlName Then
                Return c
            ElseIf c.HasChildren Then
                Dim ctl As Control = GetControlByName(ctlName, c)
                If Not (ctl Is Nothing) Then
                    Return ctl
                End If
            End If
        Next
        Return Nothing
    End Function
End Class
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 19560931
Soooooo many ways to do it...

Nice comments icr.  I just wanted to post a clear, straight forward algorithm that could be easily followed.  As you have pointed out, though, it can certainly be improved.   ;)

0
 
LVL 7

Expert Comment

by:icr
ID: 19564263
I would agree your solution is the easiest to follow. However, as the resize event gets called frequently as the form is being resized the more optimal you can make it the less "tearing" will occur. You could certainly optimise it a lot more, but then it would be harder to understand and thus maintain.
0
 
LVL 86

Expert Comment

by:Mike Tomlinson
ID: 19565616
Another idea would be to trap the WM_EXITSIZEMOVE msg and only adjust the buttons when the user lets go AFTER they finish resizing the form.
http://msdn2.microsoft.com/en-us/library/ms632623.aspx
0
 
LVL 3

Author Comment

by:FMabey
ID: 19598453
Thanks guys... I will have a look at the solutions offered and then allocated hte points accordingly.

Cheers.
0
 
LVL 3

Author Comment

by:FMabey
ID: 19623471
Just to keep this alive and to let you know I've not abandoned it... Some other things have come up which I am dealing with so I will be trying out the ideas provided as soon as I can! Thanks for our help.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

I think the Typed DataTable and Typed DataSet are very good options when working with data, but I don't like auto-generated code. First, I create an Abstract Class for my DataTables Common Code.  This class Inherits from DataTable. Also, it can …
Parsing a CSV file is a task that we are confronted with regularly, and although there are a vast number of means to do this, as a newbie, the field can be confusing and the tools can seem complex. A simple solution to parsing a customized CSV fi…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
Despite its rising prevalence in the business world, "the cloud" is still misunderstood. Some companies still believe common misconceptions about lack of security in cloud solutions and many misuses of cloud storage options still occur every day. …
Suggested Courses
Course of the Month20 days, 7 hours left to enroll

867 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question