Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Windows Forms / WinForm General / January 2007

Tip: Looking for answers? Try searching our database.

Moving the MdiClient area

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jared - 14 Jan 2007 20:27 GMT
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
Jared - 14 Jan 2007 21:06 GMT
> 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
[quoted text clipped - 12 lines]
> 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();
Jared - 14 Jan 2007 22:03 GMT
> > 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
[quoted text clipped - 20 lines]
> 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?
Bryan Phillips - 15 Jan 2007 03:50 GMT
It sounds like you are creating a dashboard.  Have you considered using
the ZoneWorkspace from the Composite UI application block?

--
Bryan Phillips
MCSD, MCDBA, MCSE
Blog:  http://bphillips76.spaces.live.com

> > > 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
[quoted text clipped - 28 lines]
> Is there any way to retain the built-in functionality of MdiClient
> without having it be a direct child of the MDI form?
Jared - 15 Jan 2007 05:00 GMT
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

> It sounds like you are creating a dashboard.  Have you considered using
> the ZoneWorkspace from the Composite UI application block?
[quoted text clipped - 36 lines]
> > Is there any way to retain the built-in functionality of MdiClient
> > without having it be a direct child of the MDI form?
Bryan Phillips - 15 Jan 2007 10:27 GMT
To learn more about CAB, check out the GotDotNet workspaces for CAB and
the Smart Client Software Factory (www.gotdotnet.com). Also check out
http://www.ideablade.com/Cabana/cabana.html and
http://www.cabpedia.com/index.php?title=Main_Page .

--
Bryan Phillips
MCSD, MCDBA, MCSE
Blog:  http://bphillips76.spaces.live.com

> 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
[quoted text clipped - 50 lines]
> > > Is there any way to retain the built-in functionality of MdiClient
> > > without having it be a direct child of the MDI form?
Mick Doherty - 15 Jan 2007 11:14 GMT
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

Signature

Mick Doherty
http://dotnetrix.co.uk/nothing.html

>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
[quoted text clipped - 12 lines]
> TIA
> Jared
Jared - 16 Jan 2007 02:20 GMT
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

> Why do you need to re-Parent the MDIClient?
>
[quoted text clipped - 25 lines]
> > TIA
> > Jared
Mick Doherty - 16 Jan 2007 12:20 GMT
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.

Signature

Mick Doherty
http://dotnetrix.co.uk/nothing.html

> Hi Mick,
>
[quoted text clipped - 47 lines]
>> > TIA
>> > Jared
Jared - 16 Jan 2007 17:01 GMT
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

> Your solution is probably as good as any.
>
[quoted text clipped - 57 lines]
> >> > TIA
> >> > Jared
Mick Doherty - 16 Jan 2007 23:35 GMT
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.

Signature

Mick Doherty
http://dotnetrix.co.uk/nothing.html

> 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.
[quoted text clipped - 11 lines]
>
> Jared

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.