MDI Layout - Horiz & Vert

NigeLost

Member
Joined
Dec 26, 2006
Messages
5
Programming Experience
Beginner
It just won't work for me!

If I use:
Me.LayoutMdi(MdiLayout.TileVertical)
Or even:
Me.LayoutMdi(System.Windows.Forms.MdiLayout.TileHorizontal)

But the tiling is a mess. Either method, I get similar results:

- two columns (three would fit more than comfortably)
- Huge gaps between the forms
- Except one column where Forms vertically overlap to fit them all in the MDI (even though autoscroll is True)

(See attached screenshot)

The code from the Horiz Menu choice is:

VB.NET:
Private Sub TileHorizontalToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TileHorizontalToolStripMenuItem.Click

Me.LayoutMdi(System.Windows.Forms.MdiLayout.TileHorizontal)

End Sub
(Cascade works just fine.)

The Forms' properties are:
Autosize = False
MaximizeBox = False
MaximumSize = 168, 406

I don't want them to resize. They must remain 168,406. I had awful-looking results when I did not restrict their dimensions and they stretched out.

Can you think of any way around this? Rearranging them manually is untidy, especially as there is no "snap to grid" feature available either.

Can anyone help?
 

Attachments

  • TilingAwry.jpg
    TilingAwry.jpg
    197.5 KB · Views: 24
The reason for that is that your child forms are not resizable. The layout is performed to use the available space most efficiently. You'll notice that the first column takes up half the width and so does the second. In the first column the top form starts at the top and the second form starts half-way down. In the second column the first form starts at the top, the second one third of the way down and the third two thirds of the way down. That is the most efficient use of the available space according to the algorithm used. It is based on the top, left corner of each form and, if the forms were resizable, they would be resized to fill their allotted areas. As they aren't resizable this second step cannot be performed. If you want some arrangement other than those standard layouts then it's up to you to position each form manually.
 
Hi,

Thanks for the explanation.

I have hammered on at this and found a solution. Someone posted an item on how to tile images on the MDI background and, together with another that spoke of centering the child, I experimented. I cobbled together some code, rehashed it a few times and it now works like a charm!

In case it helps others:

VB.NET:
        Dim X As Integer = 0
        Dim Y As Integer = 0

        Dim fWidth As Integer = 0      'Width of ChildForm 338
        Dim fHeight As Integer = 407     'Needed to set next row down

        Dim ParentWidth As Integer = 0       'Width of Parent Window Area
        Dim ParentHeight As Integer = 0      'Do I Need this? Scroll will apply anyway

        Dim ParentWidthLeft As Integer = 0  'The decrementing Width of Parent Area

        ParentWidth = Me.Width        'Captures & sets width of Parent Area
        ParentWidthLeft = ParentWidth       'Sets decrementing width to Full width

        'LOOP
        For Each f As Form In Me.MdiChildren
            fWidth = f.Width

            'Does Child fit width?

            If fWidth > ParentWidthLeft Then X = 0 : Y = Y + 407 : ParentWidthLeft = ParentWidth
            '=No, so reset ParentWidth to full, X to Zero, and Y down by 410
            'If so, then

            f.Left = X
            f.Top = Y

            ParentWidthLeft = ParentWidthLeft - fWidth
            X = X + fWidth

        Next

I am almost there with my first VB project and it has been both frustrating and fun. Being able to see the fruits of my labour is satisfying and to know that I have built a tool that will help me in my work means it has a value - I shall enjoy putting it through its paces!

Happy New Year!
 
I cannot recommend strongly enough that you NEVER use a colon to put two lines of code on one line. I also recommend never writing an If statement on a single line. They both reduce the clarity of your code. This:
VB.NET:
If fWidth > ParentWidthLeft Then X = 0 : Y = Y + 407 : ParentWidthLeft = ParentWidth
should be written like this:
VB.NET:
If fWidth > ParentWidthLeft Then
    X = 0
    Y += 407
    ParentWidthLeft = ParentWidth
End If
Also, 407 is obviously significatnt so it should not be used as a literal. It should be assigned to a variable and that variable used each time the value is required.

Finally, you should not use the Width or Height of the form itself because they include the non-client areas, i.e. the title bar and border, which are not available to the child windows. You should use the ClientSize property to get the form's internal dimensions.
 
Back
Top