Ack. Erased post. Back again. Don't ask how. Magic.

The GridLayout should be an easy thing to whip up in Windows.Forms land. I've seen a couple of attempts to bring Java's concept of Layout Management to .NET, and they are both pretty buggy and fairly complicated to fix.

So what if you only wanted a GridLayout and you didn't mind not having resizable controls and controls that overlap when the form's too small? Sounds simple, eh? It is simple.

Do note that this isn't a GridLayout as in ASP.NET, where GridLayout (in another embrace and CHANGE COMPLETELY) for MS means you can place controls on a grid with explicit x,y coords, even in an html page, just like you can in a Windows.Forms GUI RAD. No, that's not what we're doing at all. We're adding controls to your panel's Controls collection without any regard for spacing, and the GridLayout does the rest. Check the link, above. Instead of dragging to where you want it, we're letting the LayoutManager (look, a manager doing its job! give or take) do the formatting work.

So with that, I introduce the example/sample code "GridLayout made easy in VB.NET" (edited without warning). Smack this code into a form (or another control like a UserControl) and you're ready to go. Extend a form with only this code to have grid layouts all over the place. Turn appropriate vars into properties to feel better about yourself. Enjoy. (again, edited without warning; goofy formatting to fit my blogger template without wrapping)

Imports System.Windows.Forms

Public Class PnlGridLayout
    Inherits Windows.Forms.Panel

    Public intRows As Integer = 0
    ' how many rows there should be; 0 for any number 
    ' (at least one, rows or cols, must be non-zero)

    Public intCols As Integer = 6
    ' how many columns there should be; 0 for any number 
    ' (at least one, rows or cols, must be non-zero)

    Public dblRequiredHeight As Double = 0
    ' allows objects to pull how high this panel needs
    ' to be to display properly

    Public bFillColumn As Boolean = False
    ' make each control fill up all the space available 
    ' in the horizontal

    Public intCellSpacing As Integer = 3
    ' space between cells, hopefully

    Public Sub alignControls()
        Dim ctlTemp As Control
        Dim intCtrlCnt As Integer

        Dim intTempRows As Integer
        Dim intTempCols As Integer

        Dim dblRowHeight As Double
        Dim dblColWidth As Double

        Dim dblDistFromTop As Double = 0
        Dim dblTallestControlHeight As Double = 0

        dblDistFromTop = intCellSpacing

        ' have to have init'd at least one measuring stick for the grid
        ' to work.
        If Not (Me.intRows = 0 And Me.intCols = 0) Then

            ' figure out how many rows and cols we've got.
            If Me.intRows > 0 Then
                intTempRows = Me.intRows
                ' note int vs. common division usage; 
                ' might get a few cases a little closer
                intTempRows = Me.Controls.Count / Me.intCols
            End If

            If Me.intCols > 0 Then
                intTempCols = Me.intCols
                intTempCols = Me.Controls.Count / Me.intRows
            End If

            dblColWidth = Me.Width / intTempCols
            dblColWidth = dblColWidth - Me.intCellSpacing

            dblRowHeight = Me.Height / intTempRows

            For Each ctlTemp In Me.Controls
                intCtrlCnt = intCtrlCnt + 1
                With ctlTemp

                    ' have it fill the column space entirely if
                    ' preferred.
                    If Me.bFillColumn Then
                        .Width = dblColWidth - Me.intCellSpacing
                    End If

                    .Top = dblDistFromTop
                    .Left = intCellSpacing _
                        + (dblColWidth * ((intCtrlCnt Mod intTempCols) - 1))

                    If ctlTemp.Height > dblTallestControlHeight Then
                        dblTallestControlHeight = ctlTemp.Height
                    End If

                    ' fix last on row
                    If (intCtrlCnt Mod intTempCols) = 0 Then
                        .Left = dblColWidth * (intTempCols - 1)

                        If dblTallestControlHeight < dblRowHeight Then
                            dblDistFromTop = dblDistFromTop _
                                + dblTallestControlHeight + intCellSpacing
                            dblDistFromTop = dblDistFromTop _
                                + dblRowHeight + intCellSpacing
                        End If

                        dblTallestControlHeight = 0
                    End If

                    'MsgBox(intCtrlCnt & " :: " & .Top & " :: " & .Left)

                End With

            If dblTallestControlHeight = 0 Then
                Me.dblRequiredHeight = dblDistFromTop
            ElseIf dblTallestControlHeight < dblRowHeight Then
                Me.dblRequiredHeight = dblDistFromTop _
                    + dblTallestControlHeight + intCellSpacing
                Me.dblRequiredHeight = dblDistFromTop _
                    + dblRowHeight + intCellSpacing
            End If

        End If
    End Sub

    Private Sub PnlGridLayout_Resize(ByVal sender As Object, _
     ByVal e As System.EventArgs) Handles MyBase.Resize

    End Sub
End Class