Setting control to dock fill when you have a menustrip

R

Rotsey

Hi,

I have not had a good answer to this question.

I put a menustrip on a form and so it is a main menu in affect.

Now I put a webbrowser control on the form and set it dock fill.

Of course what happens is the menu covers the top of the webbrowser control
which i do not want.

Is there a property to have the control automatically drop
so it is aligned with the bottom of the menu??

Or do i have to set the top property and anchor the control etc
to achieve this, seems wrong to have to.

rotsey
 
P

Peter Duniho

Rotsey said:
I have not had a good answer to this question.

I put a menustrip on a form and so it is a main menu in affect.

Now I put a webbrowser control on the form and set it dock fill.

Of course what happens is the menu covers the top of the webbrowser control
which i do not want.

For what it's worth, the reason I didn't answer your previous post was
that the problem seemed odd to me. That is, I haven't had any trouble
having dock-filled controls overlapping the menu strip. But I didn't
have time to verify it at the time.

Since then I have had time, and I can confirm that I don't have any
trouble doing what you want to do. I drop a menu on the form, then a
control, set the control's Dock property to Fill, and it winds up flush
against the menu strip, not overlapped.

I'm using VS 2005 and .NET 2.0.

Perhaps you could post a concise-but-complete example of code that
demonstrates a form that contains a docked menu strip and a docked
control, where the control winds up overlapped with the menu strip. It
should just work, but if it doesn't for you then if you can post code
that demonstrates the problem then someone can look at it and try to
understand what's different about the code you wind up with as compared
to what the rest of us have.

It may be sufficient to just post the InitializeComponent() method for
your form, actually...so if you don't want to post the rest of the class
right off the bat, just post that method so we can look at it.

Pete
 
J

Jon Skeet [C# MVP]

Since then I have had time, and I can confirm that I don't have any
trouble doing what you want to do. I drop a menu on the form, then a
control, set the control's Dock property to Fill, and it winds up flush
against the menu strip, not overlapped.

I've seen the problem before with manual code, and I believe it
depends on the order in which components are added to the container. I
*think* the designer usually gets it right, but it's reasonably easy
to check - the component with Dock=Fill should be added first, at
least according to the code I've got in front of me :)

It's a bit of a shame that the layout engine is so sensitive to this.
Fortunately the layout options in WPF are much better - hopefully
there aren't as many niggling bits like this.

Jon
 
R

Rotsey

ok Pete here it is.

private void InitializeComponent()

{

this.components = new System.ComponentModel.Container();

System.ComponentModel.ComponentResourceManager resources = new
System.ComponentModel.ComponentResourceManager(typeof(frmMain));

this.timer1 = new System.Windows.Forms.Timer(this.components);

this.contextMenuStrip1 = new
System.Windows.Forms.ContextMenuStrip(this.components);

this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

this.deleteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

this.updateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);

this.contextMenuStrip2 = new
System.Windows.Forms.ContextMenuStrip(this.components);

this.showToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();

this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

this.menuStrip1 = new System.Windows.Forms.MenuStrip();

this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

this.newPageToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();

this.editPageToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();

this.deletePageToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();

this.toolStripMenuItem5 = new System.Windows.Forms.ToolStripSeparator();

this.ProcessDetailsToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();

this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();

this.settingsToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();

this.toolStripMenuItem3 = new System.Windows.Forms.ToolStripSeparator();

this.exitToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();

this.processToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();

this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

this.contentsToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();

this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();

this.AddPageEditorToolStripMenuItem = new
System.Windows.Forms.ToolStripMenuItem();

this.toolStripMenuItem6 = new System.Windows.Forms.ToolStripSeparator();

this.contextMenuStrip1.SuspendLayout();

this.contextMenuStrip2.SuspendLayout();

this.menuStrip1.SuspendLayout();

this.SuspendLayout();

//

// timer1

//

this.timer1.Tick += new System.EventHandler(this.timer1_Tick);

//

// contextMenuStrip1

//

this.contextMenuStrip1.Items.AddRange(new
System.Windows.Forms.ToolStripItem[] {

this.editToolStripMenuItem,

this.deleteToolStripMenuItem,

this.updateToolStripMenuItem});

this.contextMenuStrip1.Name = "contextMenuStrip1";

this.contextMenuStrip1.Size = new System.Drawing.Size(153, 92);

//

// editToolStripMenuItem

//

this.editToolStripMenuItem.Name = "editToolStripMenuItem";

this.editToolStripMenuItem.Size = new System.Drawing.Size(152, 22);

this.editToolStripMenuItem.Text = "Edit With";

this.editToolStripMenuItem.Click += new
System.EventHandler(this.editToolStripMenuItem_Click);

//

// deleteToolStripMenuItem

//

this.deleteToolStripMenuItem.Name = "deleteToolStripMenuItem";

this.deleteToolStripMenuItem.Size = new System.Drawing.Size(120, 22);

this.deleteToolStripMenuItem.Text = "Delete";

this.deleteToolStripMenuItem.Click += new
System.EventHandler(this.deleteToolStripMenuItem_Click);

//

// updateToolStripMenuItem

//

this.updateToolStripMenuItem.Name = "updateToolStripMenuItem";

this.updateToolStripMenuItem.Size = new System.Drawing.Size(120, 22);

this.updateToolStripMenuItem.Text = "Update";

this.updateToolStripMenuItem.Click += new
System.EventHandler(this.updateToolStripMenuItem_Click);

//

// notifyIcon1

//

this.notifyIcon1.ContextMenuStrip = this.contextMenuStrip2;

this.notifyIcon1.Icon =
((System.Drawing.Icon)(resources.GetObject("notifyIcon1.Icon")));

this.notifyIcon1.Text = "notifyIcon1";

this.notifyIcon1.Visible = true;

//

// contextMenuStrip2

//

this.contextMenuStrip2.Items.AddRange(new
System.Windows.Forms.ToolStripItem[] {

this.showToolStripMenuItem,

this.toolStripMenuItem1,

this.exitToolStripMenuItem});

this.contextMenuStrip2.Name = "contextMenuStrip2";

this.contextMenuStrip2.Size = new System.Drawing.Size(112, 54);

//

// showToolStripMenuItem

//

this.showToolStripMenuItem.Name = "showToolStripMenuItem";

this.showToolStripMenuItem.Size = new System.Drawing.Size(111, 22);

this.showToolStripMenuItem.Text = "Show";

this.showToolStripMenuItem.Click += new
System.EventHandler(this.showToolStripMenuItem_Click);

//

// toolStripMenuItem1

//

this.toolStripMenuItem1.Name = "toolStripMenuItem1";

this.toolStripMenuItem1.Size = new System.Drawing.Size(108, 6);

//

// exitToolStripMenuItem

//

this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";

this.exitToolStripMenuItem.Size = new System.Drawing.Size(111, 22);

this.exitToolStripMenuItem.Text = "Exit";

this.exitToolStripMenuItem.Click += new
System.EventHandler(this.menu_App_Exit);

//

// menuStrip1

//

this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {

this.fileToolStripMenuItem,

this.processToolStripMenuItem,

this.helpToolStripMenuItem});

this.menuStrip1.LayoutStyle =
System.Windows.Forms.ToolStripLayoutStyle.HorizontalStackWithOverflow;

this.menuStrip1.Location = new System.Drawing.Point(0, 0);

this.menuStrip1.Name = "menuStrip1";

this.menuStrip1.Size = new System.Drawing.Size(826, 24);

this.menuStrip1.TabIndex = 2;

this.menuStrip1.Text = "menuStrip1";

this.menuStrip1.Visible = false;

//

// fileToolStripMenuItem

//

this.fileToolStripMenuItem.DropDownItems.AddRange(new
System.Windows.Forms.ToolStripItem[] {

this.newPageToolStripMenuItem,

this.editPageToolStripMenuItem,

this.deletePageToolStripMenuItem,

this.toolStripMenuItem6,

this.AddPageEditorToolStripMenuItem,

this.toolStripMenuItem5,

this.ProcessDetailsToolStripMenuItem,

this.toolStripMenuItem2,

this.settingsToolStripMenuItem,

this.toolStripMenuItem3,

this.exitToolStripMenuItem1});

this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";

this.fileToolStripMenuItem.Size = new System.Drawing.Size(35, 20);

this.fileToolStripMenuItem.Text = "File";

//

// newPageToolStripMenuItem

//

this.newPageToolStripMenuItem.Name = "newPageToolStripMenuItem";

this.newPageToolStripMenuItem.Size = new System.Drawing.Size(162, 22);

this.newPageToolStripMenuItem.Text = "New Page";

this.newPageToolStripMenuItem.Click += new
System.EventHandler(this.newPageToolStripMenuItem_Click);

//

// editPageToolStripMenuItem

//

this.editPageToolStripMenuItem.Name = "editPageToolStripMenuItem";

this.editPageToolStripMenuItem.Size = new System.Drawing.Size(162, 22);

this.editPageToolStripMenuItem.Text = "Edit Page";

//

// deletePageToolStripMenuItem

//

this.deletePageToolStripMenuItem.Name = "deletePageToolStripMenuItem";

this.deletePageToolStripMenuItem.Size = new System.Drawing.Size(162, 22);

this.deletePageToolStripMenuItem.Text = "Delete Page";

//

// toolStripMenuItem5

//

this.toolStripMenuItem5.Name = "toolStripMenuItem5";

this.toolStripMenuItem5.Size = new System.Drawing.Size(159, 6);

//

// ProcessDetailsToolStripMenuItem

//

this.ProcessDetailsToolStripMenuItem.Name =
"ProcessDetailsToolStripMenuItem";

this.ProcessDetailsToolStripMenuItem.Size = new System.Drawing.Size(162,
22);

this.ProcessDetailsToolStripMenuItem.Text = "Process Details";

this.ProcessDetailsToolStripMenuItem.Click += new
System.EventHandler(this.ProcessDetailsToolStripMenuItem_Click);

//

// toolStripMenuItem2

//

this.toolStripMenuItem2.Name = "toolStripMenuItem2";

this.toolStripMenuItem2.Size = new System.Drawing.Size(159, 6);

//

// settingsToolStripMenuItem

//

this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem";

this.settingsToolStripMenuItem.Size = new System.Drawing.Size(162, 22);

this.settingsToolStripMenuItem.Text = "Settings";

//

// toolStripMenuItem3

//

this.toolStripMenuItem3.Name = "toolStripMenuItem3";

this.toolStripMenuItem3.Size = new System.Drawing.Size(159, 6);

//

// exitToolStripMenuItem1

//

this.exitToolStripMenuItem1.Name = "exitToolStripMenuItem1";

this.exitToolStripMenuItem1.ShortcutKeys = System.Windows.Forms.Keys.F10;

this.exitToolStripMenuItem1.Size = new System.Drawing.Size(162, 22);

this.exitToolStripMenuItem1.Text = "Exit";

this.exitToolStripMenuItem1.Click += new
System.EventHandler(this.menu_App_Exit);

//

// processToolStripMenuItem

//

this.processToolStripMenuItem.Name = "processToolStripMenuItem";

this.processToolStripMenuItem.Size = new System.Drawing.Size(56, 20);

this.processToolStripMenuItem.Text = "Process";

//

// helpToolStripMenuItem

//

this.helpToolStripMenuItem.DropDownItems.AddRange(new
System.Windows.Forms.ToolStripItem[] {

this.contentsToolStripMenuItem,

this.aboutToolStripMenuItem});

this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";

this.helpToolStripMenuItem.Size = new System.Drawing.Size(40, 20);

this.helpToolStripMenuItem.Text = "Help";

//

// contentsToolStripMenuItem

//

this.contentsToolStripMenuItem.Name = "contentsToolStripMenuItem";

this.contentsToolStripMenuItem.Size = new System.Drawing.Size(129, 22);

this.contentsToolStripMenuItem.Text = "Contents";

//

// aboutToolStripMenuItem

//

this.aboutToolStripMenuItem.Name = "aboutToolStripMenuItem";

this.aboutToolStripMenuItem.Size = new System.Drawing.Size(129, 22);

this.aboutToolStripMenuItem.Text = "About";

//

// AddPageEditorToolStripMenuItem

//

this.AddPageEditorToolStripMenuItem.Name = "AddPageEditorToolStripMenuItem";

this.AddPageEditorToolStripMenuItem.Size = new System.Drawing.Size(162, 22);

this.AddPageEditorToolStripMenuItem.Text = "Add Page Editor";

this.AddPageEditorToolStripMenuItem.Click += new
System.EventHandler(this.AddPageEditorToolStripMenuItem_Click);

//

// toolStripMenuItem6

//

this.toolStripMenuItem6.Name = "toolStripMenuItem6";

this.toolStripMenuItem6.Size = new System.Drawing.Size(159, 6);

//

// frmMain

//

this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);

this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;

this.ClientSize = new System.Drawing.Size(826, 416);

this.Controls.Add(this.menuStrip1);

this.MainMenuStrip = this.menuStrip1;

this.Name = "frmMain";

this.ShowInTaskbar = false;

this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;

this.Text = "Visual Studio";

this.Click += new System.EventHandler(this.frmMain_Click);

this.Load += new System.EventHandler(this.frmMain_Load);

this.contextMenuStrip1.ResumeLayout(false);

this.contextMenuStrip2.ResumeLayout(false);

this.menuStrip1.ResumeLayout(false);

this.menuStrip1.PerformLayout();

this.ResumeLayout(false);

this.PerformLayout();

}
 
P

Peter Duniho

Jon said:
I've seen the problem before with manual code, and I believe it
depends on the order in which components are added to the container. I
*think* the designer usually gets it right, but it's reasonably easy
to check - the component with Dock=Fill should be added first, at
least according to the code I've got in front of me :)

It's a bit of a shame that the layout engine is so sensitive to this.

I agree. The only thing that should matter, IMHO, is the actual state
of the controls. I wasn't aware of the order-dependent issue, and if it
exists that's a really annoying thing.

In some very specific cases, the state of objects change as you modify
state of other objects. An example would be the
DataGridViewColumn.DisplayIndex property, and this is specifically
documented for that property.

But this doesn't seem to be such a situation. The property values
aren't changing as different controls are added AFAIK, so the order of
operations shouldn't matter. The only hint in the documentation about
there being an order-dependent aspect is the comment that "Controls are
docked in their Z-order", but it doesn't actually say what end of the
z-order comes first with respect to docking. Duh.

I guess it's not really so much an order of operations thing as a
specific state that just happens to be affected by order of operations.
presumably you could adjust the z-order after the fact to achieve the
same results?

Anyway, back to the original question...it sounds as though it might
indeed be an ordering problem. Try making sure that the Dock=Fill
component is added first and see if that helps. :)

Pete
 
P

Peter Duniho

Rotsey said:
ok Pete here it is.

Okay. Well, I didn't see a WebBrowser control added in there at all,
never mind before the "menuStrip1" component. So that makes me think
you are adding the WebBrowser later, in your constructor or perhaps Load
event.

In that case, I'd say you almost certainly have a z-order problem.
Unfortunately, I don't actually know off the top of my head the
correlation between the order of controls in the Controls collection and
the actual z-order, but I would guess that calling
Control.BringToFront() or Control.SendToBack() on the WebBrowser control
after you add it would fix the problem.

Just a guess.

If that still doesn't do it, posting more code might help. If you do,
be sure to post a complete sample of code, but with _only_ the bare
minimum required to demonstrate the issue. A single empty menu strip,
and a plain WebBrowser control added in whatever way you're adding it
now should suffice. Don't bother including things like the context
menus or actual menu items in the menu strip, as they just clutter the
code and obscure the actual issue.

Pete
 
R

Rotsey

Well I deleted the menustrip and readded it but still the same problem.

have to say that I mislead you a little in that yes the browser
control is added at runtime.

So what I did was added a panel to the form (design view)
and dock fill it.

Then i add my browser to the panel it works fine.

So I do not know what was wrong.

But I thankyou all for your replies.

rotsey
 
C

Chris Shepherd

Jon said:
I've seen the problem before with manual code, and I believe it
depends on the order in which components are added to the container. I
*think* the designer usually gets it right, but it's reasonably easy
to check - the component with Dock=Fill should be added first, at
least according to the code I've got in front of me :)

It largely depends on how conceptually you are building your form. To
me, the menu strip will be one of the first things you need to add, but
I run into this same problem somewhat regularly where a
ToolStrip/MenuStrip are "sitting on top" of say a DataGridView.

I run into it often enough that I was confident in my ability to
reproduce it so I just created a new project, new form, added a
ToolStripMenu, then added a SplitPanel (something I most frequently have
the issue with) and set the Dock to Fill. Unfortunately, it worked
perfectly fine on a new form. When I run into it again I will copy out
the controls on the form and see if it reproduces it under similar
conditions.

Either way, it would be nice if there was some kind of DrawOrder or
ZIndex property to go along with Height/Width for more granular control
over this, or at the very least visibility to it.

Chris.
 
P

Peter Duniho

Rotsey said:
Well I deleted the menustrip and readded it but still the same problem.

have to say that I mislead you a little in that yes the browser
control is added at runtime.

So what I did was added a panel to the form (design view)
and dock fill it.

Then i add my browser to the panel it works fine.

So I do not know what was wrong.

Why not? What is still unclear to you? Are there specific aspects of
the explanations provided to you that you would like elaboration or
clarification of?

I think the various posts, between Marc's previous reply, Jon's, and my
own that it's pretty clear that the z-order is the issue here. Your
workaround seems fine, assuming you don't want to just put the
WebBrowser into the form in the designer (why you don't I don't know,
but it shouldn't be a problem one way or the other).

What is there left to explain so that you will actually understand the
behavior you're seeing? I think I speak for all of us when I say that
we don't mind adding to the answers whatever's necessary to make them
clear enough.

Pete
 
R

Rotsey

Well you say it is the z order but the problem is not only
that the webbrowser is behind the menu but also that
the webbrowser is not in the correct position.

Surely if you had a property on the menu for z order and
you set it to be in front of the control then it would be so
and also be on top of the contol covering.
Where would it be specified to the menustrip that if
the zorder from myself is lower/higher what ever than
a control in the same position that it should move the
control to a postion at the bottom of its client area.

Also the reason that I add the webbrowser control
at runtime is this was just the example of the problem
My app actually adds either of several controls
defined by some criteria to the form and dock fills
the control.

Hope this explains my thinking Pete.

rotsey
 
P

Peter Duniho

Rotsey said:
Well you say it is the z order but the problem is not only
that the webbrowser is behind the menu but also that
the webbrowser is not in the correct position.

I don't believe that you've read the replies carefully enough.

The z-order in this case affects not only how the objects on the form
are layered (that is, which is in front of which others ones) but (and
this it the part you care about) the exact position calculated for the
item with Dock=Fill.
Surely if you had a property on the menu for z order and
you set it to be in front of the control then it would be so
and also be on top of the contol covering.

Yes, but that's not the interesting part here.
Where would it be specified to the menustrip that if
the zorder from myself is lower/higher what ever than
a control in the same position that it should move the
control to a postion at the bottom of its client area.

That's how setting the Dock property to Fill works. There could be
other ways to implement it, but clearly Microsoft chose to make Fill
dependent on what other controls have already been laid out in the form,
and the order in which the controls are laid out depends on the z-order.

Thus, z-order affects how fill behavior works.

You can control how the fill behavior works by adjusting the z-order.
Also the reason that I add the webbrowser control
at runtime is this was just the example of the problem
My app actually adds either of several controls
defined by some criteria to the form and dock fills
the control.

That's fine. Why you add the control at run-time doesn't matter that
much. But IMHO you would do better by reading the replies posted so
that you actually understand why it doesn't work the way you expect.

Yes, you can work around the behavior by adding placeholder items (like
the panel) into which you add things at runtime. In fact, in this
particular instance it could even be your preferred solution. But if
you don't take the time to learn why you need the work around and what
other methods would solve the problem, then you are likely to just run
into a similar issue in the future and still not really know how to fix it.

Pete
 
R

Rotsey

Thanks for the lesson on learning Pete.

By the way what newsgroup reader do you use.

Are you able to get email notifications of posts with it??
 
P

Peter Duniho

Rotsey said:
Thanks for the lesson on learning Pete.

By the way what newsgroup reader do you use.

I'm currently using Thunderbird on my Mac. Since I've yet to find a
newsreader that I think is perfect, I switch around now and then. :)
Are you able to get email notifications of posts with it??

Not that I'm aware of. I've never seen a non-web-based newsreader that
provides email alerts. Thunderbird does include a setting to play a
sound when new messages are detected, but I don't think it's
configurable on a per-thread or per-reply basis.

If you read these newsgroups via Microsoft's web interface, I believe it
includes a setting to send you email when a reply to a post has been
made. So if you're looking for that, you might consider using that
interface.

Pete
 
R

Rotsey

I use Outlook express currently.

I am just googling for the Microsft's web base reader and cannot find a link
to it
anywhere.

You sure it exists?
 
R

Rotsey

Ok thanks.

What country are you from Pete, you seem to be the same time zone as me.??

Are you a .net developer for a living?
 

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