简体   繁体   中英

How can I control the display order of child Forms in a MDI Form

When I use an MDI Form I have a problem. My source code just like this:

private void menuItem1_Click(object sender, EventArgs e)
    {
        Form[] charr = this.MdiChildren;
        int i = 0;            
        foreach (Form chform in charr)
        {
            chform.Dock = DockStyle.Top;                
        }
        this.LayoutMdi(System.Windows.Forms.MdiLayout.TileHorizontal);
    }

The numbers of child Forms is more then 3. In order to display them correctly after the LayoutMdi() method is called, I had to set the Dock property of all child Forms to DockStyle.Top .

After calling LayoutMdi(MdiLayout.TileHorizontal) , clicking the Title Bar of the first child Form, this child Form is displayed at the bottom of the MDI parent automatically.

I want that the clicked child Form maintains it's original position.
Is there any idea for this question?

Looking at the linked question - where it was suggested to set the Dock property to adjust the MDIChild Forms position - and the currently reported behaviour, it is probably preferable to define the layout the MDIChild Forms without the help of automatic feature.

This allows to perform any layout logic that seems appropriate.

In the example, the MDIChildren.Height is calculated in relation to the MDIParent.ClientSize.Height and the number of opened MDIChildren , then multiplied by a values: in the sample code by 2, twice the base measure.

This Multiplier allows to define the Horizontal Tile Height of the MDICHildren quite precisely. Of course, you could implement some other logic that applies the multiplier only when there are at least 3 opened MDIChildren .

All the MDIChildren are re-sized to match the MDIParent.Width and the calculated Height , then ordered by Name and positioned from top to bottom.

Set different values of HorizontalTileHeightMultiplier to see how the MDIChildren are positioned in the MDIParent.ClientArea ( MdiClient ).
This multiplier could also be used as a custom Property in the Application, available to its Users allowing a custom tiling of the Forms.

The layout code is provided as a private method, so it can be easily used in different event handlers to perform/maintain the selected layout (the MDIParent.Resize , for example).
This method can also be easily adapted to replace the MdiLayout.TileVertical if required.

private float HorizontalTileHeightMultiplier = 2;

private void menuItem1_Click(object sender, EventArgs e)
{
    TileHorizontal()
}

private void TileHorizontal()
{
    int OpenedForms = Application.OpenForms.Count - 1;
    if (OpenedForms < 2) return;

    int StartLocation = 0;
    int ChildrenHeight = 
        (int)((this.ClientSize.Height / OpenedForms) * HorizontalTileHeightMultiplier);

    List<Form> children = this.MdiChildren.OrderBy(f => f.Name).ToList();
    foreach (Form child in children)
    {
        child.Size = new Size(this.ClientSize.Width - SystemInformation.VerticalScrollBarWidth - 4, ChildrenHeight);
        child.Location = new Point(0, StartLocation);
        StartLocation += ChildrenHeight;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM