Moving the MdiClient area

J

Jared

I programmatically moved the MdiClient of my MDI form to be nested
inside a Panel so I can control the layout better. I also removed the
3D border on the MdiClient using Interop.

When trying to open MDI child forms, I first received an error about
the parent not being an MDI container. I suspected this was because I
moved the MdiClient, so I set IsMdiContainer back to true after the
move. I no longer get the error, but now the MDI children don't
display at all.

I'm assuming I need to hook the MdiClient back up to the parent form
somehow. How do I do this while keeping the MdiClient nested in a
Panel?

TIA
Jared
 
J

Jared

Jared said:
I programmatically moved the MdiClient of my MDI form to be nested
inside a Panel so I can control the layout better. I also removed the
3D border on the MdiClient using Interop.

When trying to open MDI child forms, I first received an error about
the parent not being an MDI container. I suspected this was because I
moved the MdiClient, so I set IsMdiContainer back to true after the
move. I no longer get the error, but now the MDI children don't
display at all.

I'm assuming I need to hook the MdiClient back up to the parent form
somehow. How do I do this while keeping the MdiClient nested in a
Panel?

TIA
Jared

I think I tentatively solved this by setting the Parent property of the
MDI child form before displaying it:

TestForm f = new TestForm();
f.MdiParent = this; // "this" is my MDI container form
f.Parent = mdiClient; // mdiClient is a ref to the MdiClient I moved
f.Show();
 
J

Jared

Jared said:
I think I tentatively solved this by setting the Parent property of the
MDI child form before displaying it:

TestForm f = new TestForm();
f.MdiParent = this; // "this" is my MDI container form
f.Parent = mdiClient; // mdiClient is a ref to the MdiClient I moved
f.Show();

Well, that allows the child forms to be displayed, but they never
become active. In other words, they are displayed with the inactive
caption bar, and clicking on a child form will not make it appear
active.

Is there any way to retain the built-in functionality of MdiClient
without having it be a direct child of the MDI form?
 
B

Bryan Phillips

It sounds like you are creating a dashboard. Have you considered using
the ZoneWorkspace from the Composite UI application block?
 
J

Jared

Thanks for the tip, I had never heard of it. The composite UI
application block looks a lot like SharePoint for the desktop, which I
really like the *idea* of. SharePoint 1.0 was pretty limited, and came
with a whole new set of frustrating hurdles to get around. The devil's
always in the details, I guess. =)

I'm not sure I'm ready to port my app over to something like this to
solve my current problem, but I'll definitely investigate it further.
Anyhow, with a little creative work with Panels, I was able to get my
MDI interface looking just like Outlook.

Thanks again,
Jared
 
M

Mick Doherty

Why do you need to re-Parent the MDIClient?

You can dock Panels to the MDIForm to allow other controls to be added to
the view. Docking the panels modifies the MDIClient Area so that MDI Child
Forms will not obscure them.

There is an example on my site which shows this behaviour.
http://www.dotnetrix.co.uk/mdi.html
 
J

Jared

Hi Mick,

I've had the MDI client area docked all along, but I wanted to improve
the look of the UI. I did so by removing the 3D border, but I couldn't
find a way to replace it with a nice 1-pixel custom border. Normally I
would do this by nesting the control inside a Panel with
DockPadding.All = 1. In the case of MdiClient, however, this detaches
it from its Form and creates some pretty weird behavior (as described
above).

I'm sure there's a better way to accomplish this (like capturing
Windows messages and painting the border on the MdiClient control), but
I managed to solve my problem the low-tech way by creating four thin
Panels that act as the borders. I reposition them during the
MdiClient's Resize and LocationChanged events. Works great.

See a sample at:
http://www.tripletreesoftware.com/images/google_sample.jpg

Jared
 
M

Mick Doherty

Your solution is probably as good as any.

You can dock the "border panels" and then use the SendToBack and
BringToFront commands to get the correct zOrder. This will do away with the
need to reposition them at resize events.
 
J

Jared

Not to beat a dead horse, but docking the border panels didn't work for
me because that would put them on the "outside" of the MdiClient.
Which means it would be two pixels taller than the section next to it
(one on top, one on bottom) and wouldn't line up visually.

I must've tried about 10 different approaches before finally settling
on this solution. I set the z-order at Form_Load to make sure they're
on top of the MdiClient, then just reposition them as needed. Normally
I'd fight with it a little longer, but this seems to do the trick. =)

I like the custom graphics on the right side of the form caption bars
in your examples. Can you point me to a url that explains how to do
that?

Jared
 
M

Mick Doherty

OK, I see you mean the 1 pixel border around the edge. I thought you were
using panels as the pale blue padding.

You can add a standard 1 pixel border around the MdiClient in the same way
that you remove the ClientEdge.

\\\
private void MainForm_Load(object sender, EventArgs e)
{
int Style = GetWindowLong(this.mdiPanel.Handle, GWL_STYLE).ToInt32();
int ExStyle = GetWindowLong(this.mdiPanel.Handle, GWL_EXSTYLE).ToInt32();

Style |= WS_BORDER;
ExStyle &= ~WS_EX_CLIENTEDGE;

//Add standard 1 pixel border
SetWindowLong(this.mdiPanel.Handle, GWL_STYLE, (IntPtr)Style);

//Remove ClientEdge
SetWindowLong(this.mdiPanel.Handle, GWL_EXSTYLE, (IntPtr)ExStyle);

//Force a Resize so that the NonClientEdge updates.
SetWindowPos(this.mdiPanel.Handle,(IntPtr)HWND_NOTOPMOST , 0, 0, 0, 0,
((uint)(SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_FRAMECHANGED)));
}
///

note: I declared and added the MdiClient within the InitialiseComponent()
method.

i.e.
this.mdiPanel = new System.Windows.Forms.MdiClient();
--8<--
this.Controls.Add(this.mdiPanel);



The screenshot is showing the custom theme that I use, but here is an
article showing how to do it:
http://www.geekswithblogs.net/kobush/articles/CustomBorderForms.aspx

....beware of Vista though as things have changed in the NonClientArea.
 

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