How do you bring MDI child windows to the front if MDI parent has controls?

J

JohnR

Let's say I have an MDI parent form with a textbox. If I create an MDI
child form and, at runtime, move the MDI child window over the textbox on
the MDI parent, the textbox appears in front of the MDI child window.

How can I make the MDI child window appear in front of any controls that may
be on the MDI parent?

thanks, John
 
J

JohnR

Here's what I found out so far.



When you specify that a form's property "IsMDIContainer" is true, the form
creates a "MDIclient" control. You can find that object with the following
code:

For Each ctl As Control In Me.Controls

If TypeOf ctl Is MdiClient Then

Msgbox("we found an MDIclient and it's name is " & ctl.name)

End If

Next



This MDIclient control is what contains the MDIchild forms. I repeat, the
main form DOES NOT contain the MDIchild forms, it contains an MDIclient
control and it's that control that contains the MDIchild forms.

This is exactly why if you change the background color of your main form
(ie: me.backcolor = color.blue) the background color of your MDIparent does
not change! If you want to change the background color of the MDIparent you
need to first find the MDIclient (as we did in the above code snippet) and
then do a:

Ctl.backcolor = color.blue

That will change the background color of the MDIparent to blue.



Since the MDIclient is just another control in VB you can do all the normal
things you can do with controls (this is important to understanding how MDI
works). Initially, the MDIclient control has it's DOCK property set to
"full". This is why it takes up all the space in your main form. It doesn't
have to! Remember, it's just a regular control. Also realize that if you
drag a control (say, a textbox or label) on to your main form it appears
that the control is going on to the MDIparent (because at design time the
DOCK property of the MDIclient is set to FULL), but it's not. The control
is actually going on to your main form.

This behavior is the cause of my original post. The MDIchild windows are
'behind' any control on the main form because the MDIclient object is behind
the other controls. Now, since MDIclient is just another control you can
send it to the front (BringToFront) however the side effect is that the
entire MDIclient control is brought to the front, and since it's dock
property is set to 'full', you can no longer see any of your other controls
(they're being hidden). So the best I can figure out now is that you can
actually reduce the size of the MDIclient control and put you other controls
in the part of the main form that the MDIclient doesn't occupy. When you
do this you will immediately see a problem. That is, the space on the main
form that is no longer occupied by the MDIclient control has a background
color of what's in Control Panel "application background" default (usually
dark grey), and setting your main form.backcolor doesn't affect it. So in
our code we need to create a panel that will occupy the space unoccupied by
MDIclient and set the panel's backcolor to whatever we want.



Let's look at an example: Say that you have created some sort of custom
menubar that you want to put on your main form (so it's always available
regardless of any MDIchild windows that may be open). And assume that this
menubar will be on the top part of your screen. What we need to do is size
the MDIclient control so that there is room for your menubar.



Assume that your menubar takes up 50 pixels in height, and that you want
both the main form and your MDIclient control to have a background color of
light blue. Here's the code that does it:



Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load

Dim pnl As New Panel

pnl.Width = Me.Width

pnl.Anchor = AnchorStyles.Left Or AnchorStyles.Right Or
AnchorStyles.Top

pnl.Height = 57 '2 pixels bigger than needed to cover the border
of the MDIclient control

pnl.Location = New Point(0, 0) 'your panel is on the top of the
form

pnl.BackColor = Color.PowderBlue

Me.Controls.Add(pnl)



' Loop through all of the form's controls looking

' for the control of type MdiClient.

For Each ctl As Control In Me.Controls

If TypeOf ctl Is MdiClient Then

ctl.BackColor = Color.PowderBlue

ctl.Width = Me.Width

ctl.Height = Me.Height

ctl.Location = New Point(0, 55) 'this gives you room at
the top

ctl.Anchor = AnchorStyles.Left Or AnchorStyles.Bottom Or
AnchorStyles.Right Or AnchorStyles.Top

End If

Next

Me.BackColor = Color.PowderBlue



Dim frmChild As New Form 'now create a MDIchild form

frmChild.MdiParent = Me

frmChild.Show()

End Sub



What you get when you put this code into your main form's LOAD event is a
uniformly power blue form with a child window that can't be moved any closer
than 55 pixels from the top of the main form. The anchor properties keep
everything looking good as you grow and shrink the main form and the child
form.



Hope this helps to clear up how MDI works. And if anybody has a way to
solve the my original problem of having controls show up above the MDIclient
but below the MDIchild forms I'd appreciate hearing about it.
 
G

Guest

That was good analysis about the MDI forms.

I was playing around and the code that I came up w/ is really rudimentary.
The drawbacks of what I have done are

(a) It is not dynamic in nature; i.e. all the controls are on the parent are
hidden when the MDI Child form is shown and made visible when the child is
closed.

(b) everytime you minimise the child form to wrok on the parent you would
have to make the controls visible.

Anyways, here is my silly code.

\\\
Dim obj As Object
'Place this code before or after the show method of the MDIchild
For Each obj In Me.Controls
If obj.GetType.FullName <> "System.Windows.Forms.MdiClient" Then
obj.Visible = False
End If
Next obj
///

HTH
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top