Panel.Dock Fill ignoring other Panel.Dock setting

C#.NetWinformsVisual Studio-2005

C# Problem Overview


If you create a panel on a form and set it to Dock=Top and drop another panel and set its Dock=Fill, it may fill the entire form, ignoring the first panel. Changing the tab order does nothing.

C# Solutions


Solution 1 - C#

Docking layout depends on the order of sibling controls. Controls are docked "button up", so the last control in the collection is docked first. A docked control only take the layout of previously docked siblings into account. Hence the control with Dock=Fill should be first (top) in the sibling order, if you want it to take the other docked controls into account. If it is not the first control, earlier controls will overlap it.

This can be confusing because the sibling-order is not necessarily the same as the visual order, and the sibling order is not always apparent from the design view.

The Document outline window (View -> Other Windows -> Document outline) gives a useful tree-view over the control hierarchy and order, and allows you to change the sibling order of controls.

You can also change sibling order directly in the designer by context menu -> Bring to front / Send to back, which moves the control to be first or last of the siblings. These menu labels may be somewhat confusing since the actual effect depends on the layout model.

With fixed positioned controls, the 2D position is independent of the sibling order, but when controls are overlapping, the control earliest in the order will be "on top", hiding part of siblings later in the order. In this context Bring to front / Send to back makes sense.

Inside flow- or table-layout panels, the creation order determines the visual order of the controls. There is no overlapping controls. So bring to front/send to back really means make first or last in the order of controls.

With docked layout, the bring to front / send to back may be even more confusing since it determines in which order the docking is calculated, so "bring to front" on a fill-docked control will place the control in the middle of the parent, taking all edge-docked controls into account.

Solution 2 - C#

Right click on the panel with Dock=Fill and click 'Bring to Front'.

This makes this control be created last, which takes into account the Dock settings on other controls in the same container.

Solution 3 - C#

I've had the same problem and I managed to solve it.
If you have a container with DockStyle.Fill the others should also have DockStyle but Top or whatever you want.
The important thing is to add the control with DockStyle.Fill first in Controls then the others.

Example:

ComboBox cb = new ComboBox();
cb.Dock =  DockStyle.Top;

GridView gv = new GridView();
gv.Dock =  DockStyle.Fill;

Controls.Add(gv); // this is okay
Controls.Add(cb);

but if we put cb first

Controls.Add(cb);
Controls.Add(gv); // gv will overlap the combo box.

Solution 4 - C#

Another, potentially cleaner option is to use the TableLayout control. Set up one row of the desired height for your top dock, and another row to fill 100% for your bottom. Set both panels inside to Fill, and you're done.

(TableLayout does take some getting used to, though.)

Solution 5 - C#

If you don't want to change the order of the elements inside the code, you can use the method Container.Controls.SetChildIndex() with Container being the e.g. Form, Panel etc. you want do add your controls to.

Example:

     //Container ------------------------------------
     Panel Container = new Panel();

     //Top-Docked Element ---------------------------
     ButtonArea = new FlowLayoutPanel();
     Container.Controls.Add(ButtonArea);
     Container.Controls.SetChildIndex(ButtonArea, 1);
     ButtonArea.Dock = DockStyle.Top;
        
     //Fill-Docked Element --------------------------
     box = new RichTextBox();
     Container.Controls.Add(box);
     Container.Controls.SetChildIndex(box, 0); //setting this to 0 does the trick
     box.Dock = DockStyle.Fill;

Solution 6 - C#

JacquesB had the idea with the document outline but the hierarchy didn't solve my problem. My controls were not in a hierarchical style they were just listed with the same parent.

I learned that if you changed the order it will fix the way you want it to look.

The controls on the bottom of the list will overlap the controls on top of it in the Document Outline window. In your case you would make sure that the first panel is below the second panel and so forth.

Solution 7 - C#

Here is a trick that worked for me..

Place the Top item and dock it top.

Place a Splitter, and also dock it top, then set it disabled (unless you want to resize the top).

Then Place the Fill object and set Docking to Fill. The object will stay below the splitter.

Solution 8 - C#

I ran into the same issue. Mine was with adding new/custom controls below the menu strip during run time. The problem was the controls when docked, decided to dock from the top of the form and completely ignoring the menu strip entirely, very annoying if you ask me. As this had to be done dynamically with code and not during design mode this became extremely frustrating. The simplest way I found is to create a panel during design mode and dock below the menu strip. From there you can just add/remove the controls to the panel and you can dock it during run time. No need to mess with all your controls on your form that do not really need to change, too much work depending on what you really need to do.

object.dock = Fill
Panel.Controls.Add(object)

Solution 9 - C#

I know this is an old post but I discovered something useful. To adjust sibling control order programatically for dynamically created control(s), you can do something like:

parentForm.Controls.SetChildIndex (myPanel, 0) 

In my case, I did this to move a Dock/Fill panel to be the first control in my form so that it would not overlap with another docked control set to Dock/Top (a menu strip).

Solution 10 - C#

Also may be a fast solution to take the "Filled" component and right click, cut and paste in the desired area.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJeff CuscutisView Question on Stackoverflow
Solution 1 - C#JacquesBView Answer on Stackoverflow
Solution 2 - C#Jeff CuscutisView Answer on Stackoverflow
Solution 3 - C#Pandichie Anton-ValentinView Answer on Stackoverflow
Solution 4 - C#John RudyView Answer on Stackoverflow
Solution 5 - C#MarcusView Answer on Stackoverflow
Solution 6 - C#RANONOView Answer on Stackoverflow
Solution 7 - C#John ChristmanView Answer on Stackoverflow
Solution 8 - C#Robert S.View Answer on Stackoverflow
Solution 9 - C#DrLechterView Answer on Stackoverflow
Solution 10 - C#dbzView Answer on Stackoverflow