Reputation: 57
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?
Upvotes: 2
Views: 1183
Reputation: 32278
Looking at the linked question - where it was suggested to set the Dock
property to adjust the MDIChild
Forms position - and the currently reported behavior, 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)((ClientSize.Height / openedForms) * horizontalTileHeightMultiplier);
List<Form> children = MdiChildren.OrderBy(f => f.Name).ToList();
foreach (Form child in children)
{
child.Size = new Size(ClientSize.Width - SystemInformation.VerticalScrollBarWidth - 4, childrenHeight);
child.Location = new Point(0, startLocation);
startLocation += childrenHeight;
}
}
Upvotes: 2